failproofai 0.0.9-beta.1 → 0.0.9-beta.2
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/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/build-manifest.json +6 -6
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/required-server-files.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +3 -3
- package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page/build-manifest.json +3 -3
- package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +2 -2
- package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
- package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
- package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +10 -10
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js +1 -2
- package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +15 -15
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
- package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
- package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +10 -10
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/page/build-manifest.json +3 -3
- package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/policies/page/build-manifest.json +3 -3
- package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +8 -8
- package/.next/standalone/.next/server/app/policies/page.js +2 -2
- package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page/build-manifest.json +3 -3
- package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/build-manifest.json +3 -3
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +4 -3
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects/page/build-manifest.json +3 -3
- package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/projects/page.js +2 -2
- package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0g72weg._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0su~k6f._.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_codex-projects_ts_07qqk1g._.js +3 -0
- package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_0z7w.hh._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01743wx._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__092s1ta._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__09icjsf._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0.f_cyx._.js → [root-of-the-server]__0eu4j_n._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0g.lg8b._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0gs6wz4._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0h..k-e._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0it81ys._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0u4a9jq._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0dub28-._.js → [root-of-the-server]__0vrlxf2._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ymlddl._.js +18 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__11pa2ra._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__12.h2mg._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__12t-wym._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_04w00cm._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_10lm7or._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/app_0cdqd9w._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_0xerkr6._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_0q-m0y-._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/lib_codex-projects_ts_0eosib~._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/lib_utils_ts_068jk73._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{_0zaq1hm._.js → node_modules_0ttbz1~._.js} +2 -2
- package/.next/standalone/.next/server/middleware-build-manifest.js +6 -6
- package/.next/standalone/.next/server/pages/404.html +2 -2
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +9 -9
- package/.next/standalone/.next/static/chunks/{0_c_yox08g_44.js → 01q52wg_amm60.js} +2 -2
- package/.next/standalone/.next/static/chunks/03egp37o1l629.js +1 -0
- package/.next/standalone/.next/static/chunks/06j6c0ofqjy0v.js +6 -0
- package/.next/standalone/.next/static/chunks/06x4-d1~o-opr.js +1 -0
- package/.next/standalone/.next/static/chunks/{0jryicwtm9z2g.js → 0e8c_1f7-8e7t.js} +3 -3
- package/.next/standalone/.next/static/chunks/0mumk7h5i.1xd.js +1 -0
- package/.next/standalone/.next/static/chunks/0n~s0gafwnp2y.js +1 -0
- package/.next/standalone/.next/static/chunks/{0bghqwo4iloy0.js → 0zdn~84f58hvf.js} +1 -1
- package/.next/standalone/.next/static/chunks/0zig0fh30t6ou.js +1 -0
- package/.next/standalone/.next/static/chunks/{0z-jh701rc~j8.js → 10mlwc4y_kqo2.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0kzk5-mh1_x53.js → 12simlrcfk3g2.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0w1f.k~gi-y6..js → 15_mi91qaeieu.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0ufq8smh~i7wc.js → 18a9xv2p3~x.9.js} +1 -1
- package/.next/standalone/.next/static/chunks/{turbopack-0s36is87fc9r2.js → turbopack-0o7k.hakttp4k.js} +1 -1
- package/.next/standalone/app/components/cli-badge.tsx +24 -0
- package/.next/standalone/app/components/project-list.tsx +13 -7
- package/.next/standalone/app/components/sessions-list.tsx +4 -2
- package/.next/standalone/app/policies/hooks-client.tsx +66 -10
- package/.next/standalone/app/project/[name]/page.tsx +49 -22
- package/.next/standalone/app/project/[name]/session/[sessionId]/page.tsx +51 -19
- package/.next/standalone/components/reach-developers.tsx +6 -1
- package/.next/standalone/lib/codex-projects.ts +250 -0
- package/.next/standalone/lib/codex-sessions.ts +414 -0
- package/.next/standalone/lib/format-date.ts +21 -0
- package/.next/standalone/lib/log-entries.ts +3 -3
- package/.next/standalone/lib/paths.ts +13 -0
- package/.next/standalone/lib/projects.ts +57 -3
- package/.next/standalone/lib/utils.ts +6 -22
- package/.next/standalone/package.json +1 -1
- package/.next/standalone/server.js +1 -1
- package/bin/failproofai.mjs +1 -0
- package/dist/cli.mjs +1042 -122
- package/lib/codex-projects.ts +250 -0
- package/lib/codex-sessions.ts +414 -0
- package/lib/format-date.ts +21 -0
- package/lib/log-entries.ts +3 -3
- package/lib/paths.ts +13 -0
- package/lib/projects.ts +57 -3
- package/lib/utils.ts +6 -22
- package/package.json +1 -1
- package/scripts/launch.ts +2 -1
- package/src/hooks/builtin-policies.ts +7 -1
- package/src/hooks/hook-activity-store.ts +3 -0
- package/src/hooks/manager.ts +1 -1
- package/src/hooks/resolve-permission-mode.ts +6 -91
- package/.next/standalone/.next/server/chunks/[externals]__080wern._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0b57.gk._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__03rd.z8._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0e74wa-._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0vu.o-3._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0w6l33k._.js +0 -17
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0zqcovi._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__105.l_7._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_0uy6m~m._.js +0 -3
- package/.next/standalone/.next/static/chunks/00b5h4r1el.6f.js +0 -1
- package/.next/standalone/.next/static/chunks/0fw2h.g66c0h3.js +0 -1
- package/.next/standalone/.next/static/chunks/0gu87mlr5ssnt.js +0 -6
- package/.next/standalone/.next/static/chunks/0igf3xbisp1lx.js +0 -1
- package/.next/standalone/.next/static/chunks/0p5zh2diw90a1.js +0 -1
- package/.next/standalone/.next/static/chunks/0vwqucikost_q.js +0 -1
- /package/.next/standalone/.next/static/{CiVeb_yiVt-O2JYrzGzB7 → SyaO-J1hupjAiRCG-Syzg}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{CiVeb_yiVt-O2JYrzGzB7 → SyaO-J1hupjAiRCG-Syzg}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{CiVeb_yiVt-O2JYrzGzB7 → SyaO-J1hupjAiRCG-Syzg}/_ssgManifest.js +0 -0
|
@@ -5,7 +5,7 @@ import { resolveProjectPath } from "./projects";
|
|
|
5
5
|
import { resolveSubagentPath } from "./resolve-subagent-path";
|
|
6
6
|
import { runtimeCache } from "./runtime-cache";
|
|
7
7
|
import { batchAll } from "./concurrency";
|
|
8
|
-
import { formatDate } from "./
|
|
8
|
+
import { formatDate } from "./format-date";
|
|
9
9
|
import { formatDuration } from "./format-duration";
|
|
10
10
|
|
|
11
11
|
// ── Source Tagging ──
|
|
@@ -115,14 +115,14 @@ export type LogEntryType = LogEntry["type"];
|
|
|
115
115
|
|
|
116
116
|
// ── Helpers ──
|
|
117
117
|
|
|
118
|
-
function formatTimestamp(date: Date): string {
|
|
118
|
+
export function formatTimestamp(date: Date): string {
|
|
119
119
|
const base = formatDate(date);
|
|
120
120
|
const ms = date.getMilliseconds().toString().padStart(3, "0");
|
|
121
121
|
return `${base}.${ms}`;
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
/** Shared base fields present on every log entry. */
|
|
125
|
-
function baseEntry(raw: Record<string, unknown>, timestamp: string, date: Date, source: LogSource) {
|
|
125
|
+
export function baseEntry(raw: Record<string, unknown>, timestamp: string, date: Date, source: LogSource) {
|
|
126
126
|
return {
|
|
127
127
|
_source: source,
|
|
128
128
|
uuid: (raw.uuid as string) || "",
|
|
@@ -29,6 +29,19 @@ export function decodeFolderName(name: string): string {
|
|
|
29
29
|
return name.replace(/-/g, "/");
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Encodes a filesystem path into a Claude-compatible project folder name.
|
|
34
|
+
* Inverse of `decodeFolderName`.
|
|
35
|
+
*/
|
|
36
|
+
export function encodeFolderName(path: string): string {
|
|
37
|
+
// Windows drive-letter pattern: "C:/code/project" → "C--code-project"
|
|
38
|
+
const driveMatch = /^([A-Za-z]):[\\/](.*)$/.exec(path);
|
|
39
|
+
if (driveMatch) {
|
|
40
|
+
return driveMatch[1] + "--" + driveMatch[2].replace(/[\\/]/g, "-");
|
|
41
|
+
}
|
|
42
|
+
return path.replace(/[\\/]/g, "-");
|
|
43
|
+
}
|
|
44
|
+
|
|
32
45
|
export function getClaudeProjectsPath(): string {
|
|
33
46
|
// Check if path is provided via environment variable
|
|
34
47
|
const envPath = process.env.CLAUDE_PROJECTS_PATH;
|
|
@@ -11,17 +11,24 @@ import { getClaudeProjectsPath } from "./paths";
|
|
|
11
11
|
import { runtimeCache } from "./runtime-cache";
|
|
12
12
|
import { batchAll } from "./concurrency";
|
|
13
13
|
import { logWarn, logError } from "./logger";
|
|
14
|
-
import { formatDate } from "./
|
|
14
|
+
import { formatDate } from "./format-date";
|
|
15
15
|
|
|
16
16
|
export const UUID_RE = /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/;
|
|
17
17
|
export const PATH_TRAVERSAL_RE = /(^|[\\/])\.\.($|[\\/])/;
|
|
18
18
|
|
|
19
|
+
export type ProjectCli = "claude" | "codex";
|
|
20
|
+
|
|
19
21
|
export interface ProjectFolder {
|
|
20
22
|
name: string;
|
|
21
23
|
path: string;
|
|
22
24
|
isDirectory: boolean;
|
|
23
25
|
lastModified: Date;
|
|
24
26
|
lastModifiedFormatted?: string; // Pre-formatted date string to avoid hydration issues
|
|
27
|
+
/**
|
|
28
|
+
* Which agent CLIs this project's data was found in. Multiple entries when
|
|
29
|
+
* the same cwd has both Claude and Codex transcripts; rendered as badges.
|
|
30
|
+
*/
|
|
31
|
+
cli: ProjectCli[];
|
|
25
32
|
}
|
|
26
33
|
|
|
27
34
|
export interface SessionFile {
|
|
@@ -30,6 +37,9 @@ export interface SessionFile {
|
|
|
30
37
|
lastModified: Date;
|
|
31
38
|
lastModifiedFormatted?: string;
|
|
32
39
|
sessionId?: string;
|
|
40
|
+
/** Originating agent CLI. Set when the session list mixes Claude + Codex sources
|
|
41
|
+
* so the table can render a per-row CLI badge. */
|
|
42
|
+
cli?: ProjectCli;
|
|
33
43
|
}
|
|
34
44
|
|
|
35
45
|
/** Stats a path and returns mtime. Falls back to epoch (1970-01-01) on error
|
|
@@ -54,7 +64,7 @@ async function safeReaddir(dirPath: string) {
|
|
|
54
64
|
}
|
|
55
65
|
}
|
|
56
66
|
|
|
57
|
-
|
|
67
|
+
async function getClaudeProjectFolders(): Promise<ProjectFolder[]> {
|
|
58
68
|
try {
|
|
59
69
|
const projectsPath = getClaudeProjectsPath();
|
|
60
70
|
const entries = await safeReaddir(projectsPath);
|
|
@@ -72,6 +82,7 @@ export async function getProjectFolders(): Promise<ProjectFolder[]> {
|
|
|
72
82
|
isDirectory: true,
|
|
73
83
|
lastModified: mtime,
|
|
74
84
|
lastModifiedFormatted: formatDate(mtime),
|
|
85
|
+
cli: ["claude"],
|
|
75
86
|
} as ProjectFolder;
|
|
76
87
|
}),
|
|
77
88
|
16,
|
|
@@ -83,11 +94,53 @@ export async function getProjectFolders(): Promise<ProjectFolder[]> {
|
|
|
83
94
|
folders.sort((a, b) => b.lastModified.getTime() - a.lastModified.getTime());
|
|
84
95
|
return folders;
|
|
85
96
|
} catch (error) {
|
|
86
|
-
logError("Error reading project folders:", error);
|
|
97
|
+
logError("Error reading Claude project folders:", error);
|
|
87
98
|
return [];
|
|
88
99
|
}
|
|
89
100
|
}
|
|
90
101
|
|
|
102
|
+
/** Merges Claude + Codex project lists by encoded folder name. When both sources have
|
|
103
|
+
* the same name, keeps the Claude entry's `path` (so the Path column still points at
|
|
104
|
+
* `~/.claude/projects/<encoded>`), unions the `cli` arrays in [claude, codex] order,
|
|
105
|
+
* and takes the newer `lastModified`. */
|
|
106
|
+
function mergeProjectFolders(claude: ProjectFolder[], codex: ProjectFolder[]): ProjectFolder[] {
|
|
107
|
+
const byName = new Map<string, ProjectFolder>();
|
|
108
|
+
for (const f of claude) byName.set(f.name, { ...f, cli: [...f.cli] });
|
|
109
|
+
for (const f of codex) {
|
|
110
|
+
const existing = byName.get(f.name);
|
|
111
|
+
if (!existing) {
|
|
112
|
+
byName.set(f.name, { ...f, cli: [...f.cli] });
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
const mergedCli: ProjectCli[] = [...existing.cli];
|
|
116
|
+
for (const c of f.cli) if (!mergedCli.includes(c)) mergedCli.push(c);
|
|
117
|
+
const newer = f.lastModified.getTime() > existing.lastModified.getTime() ? f : existing;
|
|
118
|
+
byName.set(f.name, {
|
|
119
|
+
...existing,
|
|
120
|
+
cli: mergedCli,
|
|
121
|
+
lastModified: newer.lastModified,
|
|
122
|
+
lastModifiedFormatted: newer.lastModifiedFormatted,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
const merged = Array.from(byName.values());
|
|
126
|
+
merged.sort((a, b) => b.lastModified.getTime() - a.lastModified.getTime());
|
|
127
|
+
return merged;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export async function getProjectFolders(): Promise<ProjectFolder[]> {
|
|
131
|
+
// Lazy import to keep `lib/codex-projects.ts` out of the dep graph for callers that
|
|
132
|
+
// only need Claude helpers (e.g. CLI codepaths).
|
|
133
|
+
const { getCodexProjects } = await import("./codex-projects");
|
|
134
|
+
const [claude, codex] = await Promise.all([
|
|
135
|
+
getClaudeProjectFolders(),
|
|
136
|
+
getCodexProjects().catch((error) => {
|
|
137
|
+
logError("Error reading Codex projects:", error);
|
|
138
|
+
return [] as ProjectFolder[];
|
|
139
|
+
}),
|
|
140
|
+
]);
|
|
141
|
+
return mergeProjectFolders(claude, codex);
|
|
142
|
+
}
|
|
143
|
+
|
|
91
144
|
/**
|
|
92
145
|
* Gets the full path to a specific project folder
|
|
93
146
|
* @param projectName - Name of the project folder
|
|
@@ -157,6 +210,7 @@ export async function getSessionFiles(projectPath: string): Promise<SessionFile[
|
|
|
157
210
|
lastModified: mtime,
|
|
158
211
|
lastModifiedFormatted: formatDate(mtime),
|
|
159
212
|
sessionId: extractSessionId(entry.name),
|
|
213
|
+
cli: "claude",
|
|
160
214
|
} as SessionFile;
|
|
161
215
|
}),
|
|
162
216
|
16,
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Tailwind class-name merger.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* -
|
|
4
|
+
* `cn()` combines `clsx` (conditional class composition) with `tailwind-merge`
|
|
5
|
+
* (last-wins conflict resolution for Tailwind utility classes).
|
|
6
|
+
*
|
|
7
|
+
* Date formatting lives in lib/format-date.ts — kept separate so server-side
|
|
8
|
+
* callers don't need to load clsx/tailwind-merge just to print a timestamp.
|
|
6
9
|
*/
|
|
7
10
|
import { clsx, type ClassValue } from "clsx";
|
|
8
11
|
import { twMerge } from "tailwind-merge";
|
|
@@ -10,22 +13,3 @@ import { twMerge } from "tailwind-merge";
|
|
|
10
13
|
export function cn(...inputs: ClassValue[]) {
|
|
11
14
|
return twMerge(clsx(inputs));
|
|
12
15
|
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Formats a date to a readable string format (e.g., "Jan 15, 2024, 3:45 PM").
|
|
16
|
-
*
|
|
17
|
-
* Creates a new Intl.DateTimeFormat on each call intentionally — this runs
|
|
18
|
-
* server-side where there's no shared state concern. The client-side hot-path
|
|
19
|
-
* formatter in lib/log-format.ts caches its instance at module scope instead.
|
|
20
|
-
*/
|
|
21
|
-
export function formatDate(date: Date): string {
|
|
22
|
-
return new Intl.DateTimeFormat("en-US", {
|
|
23
|
-
month: "short",
|
|
24
|
-
day: "numeric",
|
|
25
|
-
year: "numeric",
|
|
26
|
-
hour: "numeric",
|
|
27
|
-
minute: "2-digit",
|
|
28
|
-
hour12: true,
|
|
29
|
-
}).format(date);
|
|
30
|
-
}
|
|
31
|
-
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "failproofai",
|
|
3
|
-
"version": "0.0.9-beta.
|
|
3
|
+
"version": "0.0.9-beta.2",
|
|
4
4
|
"description": "The easiest way to manage policies that keep your AI agents reliable, on-task, and running autonomously — for Claude Code & the Agents SDK",
|
|
5
5
|
"bin": {
|
|
6
6
|
"failproofai": "./dist/cli.mjs"
|
|
@@ -9,7 +9,7 @@ const currentPort = parseInt(process.env.PORT, 10) || 3000
|
|
|
9
9
|
const hostname = process.env.HOSTNAME || '0.0.0.0'
|
|
10
10
|
|
|
11
11
|
let keepAliveTimeout = parseInt(process.env.KEEP_ALIVE_TIMEOUT, 10)
|
|
12
|
-
const nextConfig = {"env":{"NEXT_PUBLIC_APP_VERSION":"0.0.9-beta.
|
|
12
|
+
const nextConfig = {"env":{"NEXT_PUBLIC_APP_VERSION":"0.0.9-beta.2"},"typescript":{"ignoreBuildErrors":false},"typedRoutes":false,"distDir":"./.next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.ts","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"poweredByHeader":true,"compress":true,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":14400,"formats":["image/webp"],"maximumRedirects":3,"maximumResponseBody":50000000,"dangerouslyAllowLocalIP":false,"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"attachment","localPatterns":[{"pathname":"**","search":""}],"remotePatterns":[],"qualities":[75],"unoptimized":true,"customCacheHandler":false},"devIndicators":{"position":"bottom-left"},"onDemandEntries":{"maxInactiveAge":60000,"pagesBufferLength":5},"basePath":"","sassOptions":{},"trailingSlash":false,"i18n":null,"productionBrowserSourceMaps":false,"excludeDefaultMomentLocales":true,"reactProductionProfiling":false,"reactStrictMode":null,"reactMaxHeadersLength":6000,"httpAgentOptions":{"keepAlive":true},"logging":{"serverFunctions":true,"browserToTerminal":"warn"},"compiler":{},"expireTime":31536000,"staticPageGenerationTimeout":60,"output":"standalone","modularizeImports":{"@mui/icons-material":{"transform":"@mui/icons-material/{{member}}"},"lodash":{"transform":"lodash/{{member}}"}},"outputFileTracingRoot":"/home/runner/work/failproofai/failproofai","cacheComponents":false,"cacheLife":{"default":{"stale":300,"revalidate":900,"expire":4294967294},"seconds":{"stale":30,"revalidate":1,"expire":60},"minutes":{"stale":300,"revalidate":60,"expire":3600},"hours":{"stale":300,"revalidate":3600,"expire":86400},"days":{"stale":300,"revalidate":86400,"expire":604800},"weeks":{"stale":300,"revalidate":604800,"expire":2592000},"max":{"stale":300,"revalidate":2592000,"expire":31536000}},"cacheHandlers":{},"experimental":{"appNewScrollHandler":false,"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"cachedNavigations":false,"partialFallbacks":false,"dynamicOnHover":false,"varyParams":false,"prefetchInlining":false,"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":3,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"imgOptSkipMetadata":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"strictRouteTypes":false,"viewTransition":false,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":false,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":true,"serverComponentsHmrCache":true,"staticGenerationMaxConcurrency":8,"staticGenerationMinPagesPerWorker":25,"transitionIndicator":false,"gestureTransition":false,"inlineCss":false,"useCache":false,"globalNotFound":false,"browserDebugInfoInTerminal":"warn","lockDistDir":true,"proxyClientMaxBodySize":10485760,"hideLogsAfterAbort":false,"mcpServer":true,"turbopackFileSystemCacheForDev":true,"turbopackFileSystemCacheForBuild":false,"turbopackInferModuleSideEffects":true,"turbopackPluginRuntimeStrategy":"childProcesses","optimizePackageImports":["lucide-react","date-fns","lodash-es","ramda","antd","react-bootstrap","ahooks","@ant-design/icons","@headlessui/react","@headlessui-float/react","@heroicons/react/20/solid","@heroicons/react/24/solid","@heroicons/react/24/outline","@visx/visx","@tremor/react","rxjs","@mui/material","@mui/icons-material","recharts","react-use","effect","@effect/schema","@effect/platform","@effect/platform-node","@effect/platform-browser","@effect/platform-bun","@effect/sql","@effect/sql-mssql","@effect/sql-mysql2","@effect/sql-pg","@effect/sql-sqlite-node","@effect/sql-sqlite-bun","@effect/sql-sqlite-wasm","@effect/sql-sqlite-react-native","@effect/rpc","@effect/rpc-http","@effect/typeclass","@effect/experimental","@effect/opentelemetry","@material-ui/core","@material-ui/icons","@tabler/icons-react","mui-core","react-icons/ai","react-icons/bi","react-icons/bs","react-icons/cg","react-icons/ci","react-icons/di","react-icons/fa","react-icons/fa6","react-icons/fc","react-icons/fi","react-icons/gi","react-icons/go","react-icons/gr","react-icons/hi","react-icons/hi2","react-icons/im","react-icons/io","react-icons/io5","react-icons/lia","react-icons/lib","react-icons/lu","react-icons/md","react-icons/pi","react-icons/ri","react-icons/rx","react-icons/si","react-icons/sl","react-icons/tb","react-icons/tfi","react-icons/ti","react-icons/vsc","react-icons/wi"],"trustHostHeader":false,"isExperimentalCompile":false},"htmlLimitedBots":"[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight","bundlePagesRouterDependencies":false,"configFileName":"next.config.ts","outputFileTracingExcludes":{"*":["node_modules/@img/**","node_modules/sharp/**"]},"turbopack":{"root":"/home/runner/work/failproofai/failproofai"},"distDirRoot":".next"}
|
|
13
13
|
|
|
14
14
|
process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(nextConfig)
|
|
15
15
|
|
package/bin/failproofai.mjs
CHANGED
|
@@ -148,6 +148,7 @@ EXAMPLES
|
|
|
148
148
|
LINKS
|
|
149
149
|
⭐ Star us: https://github.com/exospherehost/failproofai
|
|
150
150
|
📖 Docs: https://befailproof.ai
|
|
151
|
+
💬 Slack: https://join.slack.com/t/failproofai/shared_invite/zt-3v63b7k5e-O3NBHmj8X6n9gZSGDx6ggQ
|
|
151
152
|
`.trimStart());
|
|
152
153
|
process.exit(0);
|
|
153
154
|
}
|