fapony 0.3.3 → 0.3.4
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/fapony.ts +3 -116
- package/package.json +2 -2
- package/skill/move-to-done/SKILL.md +3 -2
- package/src/adapters/cli.ts +123 -0
- package/src/adapters/hooks/compute-hint-impact.ts +107 -0
- package/src/adapters/hooks/context-data.ts +102 -0
- package/src/adapters/hooks/edit-hint.ts +195 -0
- package/src/adapters/hooks/git-autonomy.ts +178 -0
- package/src/adapters/hooks/index.ts +79 -0
- package/src/adapters/hooks/mv-guard.ts +52 -0
- package/src/adapters/hooks/read-hint.ts +383 -0
- package/src/adapters/hooks/session-start.ts +101 -0
- package/src/adapters/hooks/stop.ts +302 -0
- package/src/{mcp → adapters/mcp}/evidence.ts +2 -2
- package/src/{mcp → adapters/mcp}/primitives.ts +2 -2
- package/src/{mcp → adapters/mcp}/tools/check.ts +1 -1
- package/src/{mcp → adapters/mcp}/tools/collect.ts +1 -1
- package/src/{mcp → adapters/mcp}/tools/mem.ts +3 -3
- package/src/{mcp → adapters/mcp}/tools/report.ts +4 -4
- package/src/adapters/mcp/types.ts +18 -0
- package/src/{mcp → adapters/mcp}/worktree.ts +1 -1
- package/src/analyze.ts +1 -1
- package/src/conventions-seed.ts +1 -1
- package/src/core/config.ts +199 -0
- package/src/core/debt-format.ts +107 -0
- package/src/core/debt-types.ts +79 -0
- package/src/core/defaults.ts +8 -0
- package/src/core/enums.ts +34 -0
- package/src/core/format.ts +33 -0
- package/src/core/hint-log.ts +68 -0
- package/src/core/hook-helpers.ts +31 -0
- package/src/core/mem-log.ts +357 -0
- package/src/core/parse.ts +71 -0
- package/src/core/pricing.ts +217 -0
- package/src/core/safety.ts +18 -0
- package/src/core/types.ts +142 -0
- package/src/core/util.ts +105 -0
- package/src/db/store.ts +2 -2
- package/src/debt/cli.ts +1 -1
- package/src/debt/format.ts +2 -107
- package/src/debt/load.ts +1 -1
- package/src/debt/promotion.ts +1 -1
- package/src/debt/types.ts +14 -79
- package/src/digest/collect.ts +4 -3
- package/src/gate.ts +2 -2
- package/src/gates.ts +1 -1
- package/src/hook.ts +69 -1424
- package/src/init-mem.ts +1 -1
- package/src/init.ts +1 -1
- package/src/install/claude.ts +17 -0
- package/src/install/opencode.ts +114 -0
- package/src/install.ts +12 -5
- package/src/lint-baseline.ts +1 -2
- package/src/map.ts +29 -8
- package/src/mem/commands/plan.ts +70 -42
- package/src/mem/store.ts +5 -1
- package/src/memory.ts +24 -387
- package/src/parse.ts +9 -71
- package/src/price/fetch.ts +4 -16
- package/src/price/resolve.ts +12 -213
- package/src/report/cli.ts +3 -3
- package/src/safety.ts +2 -18
- package/src/seed/plan-seed.ts +8 -4
- package/src/seed/primitives.ts +1 -7
- package/src/session/types.ts +14 -128
- package/src/setup.ts +1 -1
- package/src/stats/data.ts +3 -3
- package/src/telemetry.ts +2 -2
- package/src/usage/cache.ts +1 -2
- package/src/usage/cli.ts +1 -1
- package/src/usage/scan.ts +2 -1
- package/src/util.ts +10 -93
- package/src/web/html.ts +2 -33
- package/src/db/defaults.ts +0 -34
- package/src/db/getters.ts +0 -35
- package/src/db/index.ts +0 -7
- package/src/db/load.ts +0 -57
- package/src/db/types.ts +0 -77
- package/src/mcp/types.ts +0 -54
- /package/src/{mcp → adapters/mcp}/tools/index.ts +0 -0
- /package/src/{mcp → adapters/mcp}/transport.ts +0 -0
package/src/db/defaults.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import type { Config } from "./types.js";
|
|
2
|
-
|
|
3
|
-
export const DEFAULT_SAFETY_DENY = [
|
|
4
|
-
"reset\\s+--hard",
|
|
5
|
-
"clean\\s+-[a-z]*f",
|
|
6
|
-
"checkout\\s+--\\s",
|
|
7
|
-
"git\\s+stash",
|
|
8
|
-
];
|
|
9
|
-
// --- .fapony/ layout (single source of truth — do not hardcode ".fapony" elsewhere) ---
|
|
10
|
-
// plan/spec live in .fapony/ — not configurable (gitignored = private).
|
|
11
|
-
export const FAPONY_DIR = ".fapony";
|
|
12
|
-
export const CONFIG_FILENAME = "fapony.config.json";
|
|
13
|
-
export const CONVENTIONS_FILENAME = "conventions.json";
|
|
14
|
-
export const EVIDENCE_FILENAME = "evidence.json";
|
|
15
|
-
export const CONVENTIONS_FILE = `${FAPONY_DIR}/${CONVENTIONS_FILENAME}`;
|
|
16
|
-
// plan/spec live in .fapony/ — not configurable (gitignored = private).
|
|
17
|
-
export const PLAN_DIR = `${FAPONY_DIR}/plan`;
|
|
18
|
-
export const SPEC_DIR = `${FAPONY_DIR}/spec`;
|
|
19
|
-
// Archive sits beside plan/, not inside it, so archiving never changes a file's
|
|
20
|
-
// depth and its relative links survive the move untouched.
|
|
21
|
-
export const DEFAULT_DONE_DIR = `${FAPONY_DIR}/done`;
|
|
22
|
-
export const DEFAULT_MEM_DIR = `${FAPONY_DIR}/.memory`;
|
|
23
|
-
export const DEFAULT_EVIDENCE_FILE = `${FAPONY_DIR}/${EVIDENCE_FILENAME}`;
|
|
24
|
-
|
|
25
|
-
export const DEFAULT_CONFIG: Config = {
|
|
26
|
-
worktrees: {},
|
|
27
|
-
review: {
|
|
28
|
-
maxRounds: 2,
|
|
29
|
-
},
|
|
30
|
-
memory: null,
|
|
31
|
-
telemetry: null,
|
|
32
|
-
paths: null,
|
|
33
|
-
safety: null,
|
|
34
|
-
};
|
package/src/db/getters.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DEFAULT_DONE_DIR,
|
|
3
|
-
DEFAULT_EVIDENCE_FILE,
|
|
4
|
-
DEFAULT_MEM_DIR,
|
|
5
|
-
DEFAULT_SAFETY_DENY,
|
|
6
|
-
PLAN_DIR,
|
|
7
|
-
SPEC_DIR,
|
|
8
|
-
} from "./defaults.js";
|
|
9
|
-
import type { Config } from "./types.js";
|
|
10
|
-
|
|
11
|
-
export function safetyDeny(config?: Config): string[] {
|
|
12
|
-
return config?.safety?.deny ?? DEFAULT_SAFETY_DENY;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/** Hardcoded — plan/spec live in .fapony/ (gitignored = private). */
|
|
16
|
-
export function planDir(): string {
|
|
17
|
-
return PLAN_DIR;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/** Hardcoded — plan/spec live in .fapony/ (gitignored = private). */
|
|
21
|
-
export function specDir(): string {
|
|
22
|
-
return SPEC_DIR;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function doneDir(config?: Config): string {
|
|
26
|
-
return config?.paths?.doneDir ?? DEFAULT_DONE_DIR;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function memoryDir(config?: Config): string {
|
|
30
|
-
return config?.paths?.memDir ?? DEFAULT_MEM_DIR;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export function evidenceFile(config?: Config): string {
|
|
34
|
-
return config?.paths?.evidenceFile ?? DEFAULT_EVIDENCE_FILE;
|
|
35
|
-
}
|
package/src/db/index.ts
DELETED
package/src/db/load.ts
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
-
import { homedir } from "node:os";
|
|
3
|
-
import { join } from "node:path";
|
|
4
|
-
import { CONFIG_FILENAME, DEFAULT_CONFIG } from "./defaults.js";
|
|
5
|
-
import type { Config } from "./types.js";
|
|
6
|
-
|
|
7
|
-
// XDG Base Directory convention (macOS ignores Apple's ~/Library/Application Support
|
|
8
|
-
// for CLI tools by common practice — gh, ripgrep-adjacent tools, etc. use ~/.config too)
|
|
9
|
-
// Override order: $FAPONY_STATE_DIR > config.paths.stateDir > $XDG_CONFIG_HOME > ~/.config
|
|
10
|
-
export function faponyDir(config?: Config): string {
|
|
11
|
-
if (process.env.FAPONY_STATE_DIR) return process.env.FAPONY_STATE_DIR;
|
|
12
|
-
if (config?.paths?.stateDir) return config.paths.stateDir;
|
|
13
|
-
const base = process.env.XDG_CONFIG_HOME || join(homedir(), ".config");
|
|
14
|
-
return join(base, "fapony");
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function _dbPath(config?: Config): string {
|
|
18
|
-
return join(faponyDir(config), "state.db");
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export function configFilePath(): string {
|
|
22
|
-
if (process.env.FAPONY_CONFIG) return process.env.FAPONY_CONFIG;
|
|
23
|
-
return join(process.cwd(), CONFIG_FILENAME);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function freshDefaultConfig(): Config {
|
|
27
|
-
return {
|
|
28
|
-
...DEFAULT_CONFIG,
|
|
29
|
-
worktrees: { ...DEFAULT_CONFIG.worktrees },
|
|
30
|
-
review: {
|
|
31
|
-
...DEFAULT_CONFIG.review,
|
|
32
|
-
},
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export function loadConfig(configPath?: string): Config {
|
|
37
|
-
const resolved = configPath ?? configFilePath();
|
|
38
|
-
if (!existsSync(resolved)) return freshDefaultConfig();
|
|
39
|
-
|
|
40
|
-
try {
|
|
41
|
-
const raw = readFileSync(resolved, "utf-8");
|
|
42
|
-
const file = JSON.parse(raw) as Partial<Config>;
|
|
43
|
-
|
|
44
|
-
return {
|
|
45
|
-
...DEFAULT_CONFIG,
|
|
46
|
-
...file,
|
|
47
|
-
review: {
|
|
48
|
-
...DEFAULT_CONFIG.review,
|
|
49
|
-
...file.review,
|
|
50
|
-
},
|
|
51
|
-
paths: file.paths ? { ...file.paths } : DEFAULT_CONFIG.paths,
|
|
52
|
-
safety: file.safety ? { ...file.safety } : DEFAULT_CONFIG.safety,
|
|
53
|
-
};
|
|
54
|
-
} catch {
|
|
55
|
-
return freshDefaultConfig();
|
|
56
|
-
}
|
|
57
|
-
}
|
package/src/db/types.ts
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
export type RunStatus =
|
|
2
|
-
| "running"
|
|
3
|
-
| "awaiting_review"
|
|
4
|
-
| "fixing"
|
|
5
|
-
| "passed"
|
|
6
|
-
| "stopped"
|
|
7
|
-
| "stalled";
|
|
8
|
-
|
|
9
|
-
export interface Run {
|
|
10
|
-
id: number;
|
|
11
|
-
worktree: string;
|
|
12
|
-
plan: string | null;
|
|
13
|
-
mem_id: string | null;
|
|
14
|
-
status: RunStatus;
|
|
15
|
-
base_sha: string;
|
|
16
|
-
round: number;
|
|
17
|
-
created_at: string;
|
|
18
|
-
updated_at: string;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface Event {
|
|
22
|
-
id: number;
|
|
23
|
-
run_id: number;
|
|
24
|
-
ts: string;
|
|
25
|
-
kind: string;
|
|
26
|
-
data: string | null;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export interface Config {
|
|
30
|
-
worktrees: Record<string, string>;
|
|
31
|
-
review: {
|
|
32
|
-
maxRounds: number;
|
|
33
|
-
};
|
|
34
|
-
memory: {
|
|
35
|
-
claim: string[];
|
|
36
|
-
close: string[];
|
|
37
|
-
add: string[];
|
|
38
|
-
kickoff?: string[];
|
|
39
|
-
} | null;
|
|
40
|
-
// opt-in only — omit or leave null to keep everything local. See TELEMETRY.md
|
|
41
|
-
// for the exact payload shape (KPI numbers + event kind/timestamp, no
|
|
42
|
-
// plan/commit/gate-note content, ever).
|
|
43
|
-
telemetry?: {
|
|
44
|
-
enabled: boolean;
|
|
45
|
-
endpoint: string;
|
|
46
|
-
/** Self-reported metadata — advisory, not machine-observed. */
|
|
47
|
-
metadata?: {
|
|
48
|
-
task_category?: string;
|
|
49
|
-
stack?: string;
|
|
50
|
-
notes?: string;
|
|
51
|
-
};
|
|
52
|
-
} | null;
|
|
53
|
-
// --- Flexible paths / limits (all optional, defaults = old hardcodes) ---
|
|
54
|
-
paths?: {
|
|
55
|
-
// state dir override (default: $XDG_CONFIG_HOME/fapony or ~/.config/fapony).
|
|
56
|
-
// $FAPONY_STATE_DIR env wins over this when set.
|
|
57
|
-
stateDir?: string;
|
|
58
|
-
// plan/spec live in .fapony/{plan,spec} — not configurable (gitignored = private).
|
|
59
|
-
doneDir?: string;
|
|
60
|
-
memDir?: string;
|
|
61
|
-
evidenceFile?: string;
|
|
62
|
-
} | null;
|
|
63
|
-
safety?: {
|
|
64
|
-
// regex sources tested against the joined argv; default = the 4 git patterns.
|
|
65
|
-
deny?: string[];
|
|
66
|
-
} | null;
|
|
67
|
-
usageWeb?: {
|
|
68
|
-
port?: number;
|
|
69
|
-
hostname?: string;
|
|
70
|
-
ownerName?: string;
|
|
71
|
-
} | null;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export interface RolePricing {
|
|
75
|
-
inputPer1k: number;
|
|
76
|
-
outputPer1k: number;
|
|
77
|
-
}
|
package/src/mcp/types.ts
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
// src/mcp/types.ts — ReasonCode enum, ToolResult, helpers
|
|
2
|
-
|
|
3
|
-
// --- ReasonCode enum (locked in step 0, append-only) ---
|
|
4
|
-
|
|
5
|
-
export const REASON_CODES = [
|
|
6
|
-
"missing_test",
|
|
7
|
-
"scope_mismatch",
|
|
8
|
-
"unsafe_command",
|
|
9
|
-
"spec_gap",
|
|
10
|
-
"timeout",
|
|
11
|
-
"blocked",
|
|
12
|
-
"incomplete",
|
|
13
|
-
"none",
|
|
14
|
-
"other",
|
|
15
|
-
] as const;
|
|
16
|
-
|
|
17
|
-
export type ReasonCode = (typeof REASON_CODES)[number];
|
|
18
|
-
|
|
19
|
-
// --- RegimeCode enum (task-shape axis for model × project × regime × quality) ---
|
|
20
|
-
|
|
21
|
-
export const REGIME_CODES = [
|
|
22
|
-
"code",
|
|
23
|
-
"fix",
|
|
24
|
-
"review",
|
|
25
|
-
"plan",
|
|
26
|
-
"inquiry",
|
|
27
|
-
"test",
|
|
28
|
-
] as const;
|
|
29
|
-
|
|
30
|
-
export type RegimeCode = (typeof REGIME_CODES)[number];
|
|
31
|
-
|
|
32
|
-
// --- Tool result types ---
|
|
33
|
-
|
|
34
|
-
export interface ToolResult {
|
|
35
|
-
content: { type: "text"; text: string }[];
|
|
36
|
-
isError?: boolean;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export function jsonResult(data: unknown): ToolResult {
|
|
40
|
-
return {
|
|
41
|
-
content: [{ type: "text", text: JSON.stringify(data) }],
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export function errorResult(message: string): ToolResult {
|
|
46
|
-
return {
|
|
47
|
-
content: [{ type: "text", text: JSON.stringify({ error: message }) }],
|
|
48
|
-
isError: true,
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export function parseToolResult(result: ToolResult): unknown {
|
|
53
|
-
return JSON.parse(result.content[0].text);
|
|
54
|
-
}
|
|
File without changes
|
|
File without changes
|