briefops 1.0.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/CHANGELOG.md +36 -0
- package/CODE_OF_CONDUCT.md +13 -0
- package/CONTRIBUTING.md +53 -0
- package/LICENSE +21 -0
- package/README.md +801 -0
- package/SECURITY.md +59 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +54 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/approve.d.ts +2 -0
- package/dist/commands/approve.js +38 -0
- package/dist/commands/approve.js.map +1 -0
- package/dist/commands/brief.d.ts +2 -0
- package/dist/commands/brief.js +81 -0
- package/dist/commands/brief.js.map +1 -0
- package/dist/commands/codex.d.ts +2 -0
- package/dist/commands/codex.js +163 -0
- package/dist/commands/codex.js.map +1 -0
- package/dist/commands/compare.d.ts +2 -0
- package/dist/commands/compare.js +48 -0
- package/dist/commands/compare.js.map +1 -0
- package/dist/commands/continue.d.ts +2 -0
- package/dist/commands/continue.js +66 -0
- package/dist/commands/continue.js.map +1 -0
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.js +90 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/eval.d.ts +2 -0
- package/dist/commands/eval.js +89 -0
- package/dist/commands/eval.js.map +1 -0
- package/dist/commands/export.d.ts +2 -0
- package/dist/commands/export.js +105 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/finish.d.ts +2 -0
- package/dist/commands/finish.js +71 -0
- package/dist/commands/finish.js.map +1 -0
- package/dist/commands/handoff.d.ts +2 -0
- package/dist/commands/handoff.js +77 -0
- package/dist/commands/handoff.js.map +1 -0
- package/dist/commands/inbox.d.ts +2 -0
- package/dist/commands/inbox.js +36 -0
- package/dist/commands/inbox.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.js +13 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/inspect.d.ts +2 -0
- package/dist/commands/inspect.js +226 -0
- package/dist/commands/inspect.js.map +1 -0
- package/dist/commands/log.d.ts +2 -0
- package/dist/commands/log.js +96 -0
- package/dist/commands/log.js.map +1 -0
- package/dist/commands/memory.d.ts +2 -0
- package/dist/commands/memory.js +236 -0
- package/dist/commands/memory.js.map +1 -0
- package/dist/commands/pack.d.ts +2 -0
- package/dist/commands/pack.js +42 -0
- package/dist/commands/pack.js.map +1 -0
- package/dist/commands/prime.d.ts +4 -0
- package/dist/commands/prime.js +44 -0
- package/dist/commands/prime.js.map +1 -0
- package/dist/commands/project.d.ts +2 -0
- package/dist/commands/project.js +50 -0
- package/dist/commands/project.js.map +1 -0
- package/dist/commands/shared.d.ts +3 -0
- package/dist/commands/shared.js +24 -0
- package/dist/commands/shared.js.map +1 -0
- package/dist/commands/skill.d.ts +2 -0
- package/dist/commands/skill.js +146 -0
- package/dist/commands/skill.js.map +1 -0
- package/dist/commands/worker.d.ts +2 -0
- package/dist/commands/worker.js +128 -0
- package/dist/commands/worker.js.map +1 -0
- package/dist/core/adapter.d.ts +22 -0
- package/dist/core/adapter.js +167 -0
- package/dist/core/adapter.js.map +1 -0
- package/dist/core/approval.d.ts +26 -0
- package/dist/core/approval.js +86 -0
- package/dist/core/approval.js.map +1 -0
- package/dist/core/brief.d.ts +47 -0
- package/dist/core/brief.js +411 -0
- package/dist/core/brief.js.map +1 -0
- package/dist/core/codex.d.ts +53 -0
- package/dist/core/codex.js +286 -0
- package/dist/core/codex.js.map +1 -0
- package/dist/core/codexPlugin.d.ts +51 -0
- package/dist/core/codexPlugin.js +228 -0
- package/dist/core/codexPlugin.js.map +1 -0
- package/dist/core/compatibility.d.ts +2 -0
- package/dist/core/compatibility.js +16 -0
- package/dist/core/compatibility.js.map +1 -0
- package/dist/core/config.d.ts +19 -0
- package/dist/core/config.js +77 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/contextBudget.d.ts +12 -0
- package/dist/core/contextBudget.js +22 -0
- package/dist/core/contextBudget.js.map +1 -0
- package/dist/core/contextCompare.d.ts +27 -0
- package/dist/core/contextCompare.js +97 -0
- package/dist/core/contextCompare.js.map +1 -0
- package/dist/core/continuity.d.ts +25 -0
- package/dist/core/continuity.js +73 -0
- package/dist/core/continuity.js.map +1 -0
- package/dist/core/errors.d.ts +4 -0
- package/dist/core/errors.js +12 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/eval.d.ts +38 -0
- package/dist/core/eval.js +180 -0
- package/dist/core/eval.js.map +1 -0
- package/dist/core/exportPolicy.d.ts +7 -0
- package/dist/core/exportPolicy.js +17 -0
- package/dist/core/exportPolicy.js.map +1 -0
- package/dist/core/exportTargets.d.ts +25 -0
- package/dist/core/exportTargets.js +292 -0
- package/dist/core/exportTargets.js.map +1 -0
- package/dist/core/handoff.d.ts +48 -0
- package/dist/core/handoff.js +611 -0
- package/dist/core/handoff.js.map +1 -0
- package/dist/core/inbox.d.ts +15 -0
- package/dist/core/inbox.js +56 -0
- package/dist/core/inbox.js.map +1 -0
- package/dist/core/lock.d.ts +11 -0
- package/dist/core/lock.js +99 -0
- package/dist/core/lock.js.map +1 -0
- package/dist/core/log.d.ts +38 -0
- package/dist/core/log.js +93 -0
- package/dist/core/log.js.map +1 -0
- package/dist/core/memory.d.ts +86 -0
- package/dist/core/memory.js +353 -0
- package/dist/core/memory.js.map +1 -0
- package/dist/core/memoryHygiene.d.ts +25 -0
- package/dist/core/memoryHygiene.js +95 -0
- package/dist/core/memoryHygiene.js.map +1 -0
- package/dist/core/memoryProposal.d.ts +40 -0
- package/dist/core/memoryProposal.js +279 -0
- package/dist/core/memoryProposal.js.map +1 -0
- package/dist/core/output.d.ts +7 -0
- package/dist/core/output.js +18 -0
- package/dist/core/output.js.map +1 -0
- package/dist/core/patch.d.ts +37 -0
- package/dist/core/patch.js +220 -0
- package/dist/core/patch.js.map +1 -0
- package/dist/core/paths.d.ts +33 -0
- package/dist/core/paths.js +84 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/core/prime.d.ts +17 -0
- package/dist/core/prime.js +298 -0
- package/dist/core/prime.js.map +1 -0
- package/dist/core/privacyDoctor.d.ts +14 -0
- package/dist/core/privacyDoctor.js +59 -0
- package/dist/core/privacyDoctor.js.map +1 -0
- package/dist/core/project.d.ts +16 -0
- package/dist/core/project.js +73 -0
- package/dist/core/project.js.map +1 -0
- package/dist/core/securityDoctor.d.ts +14 -0
- package/dist/core/securityDoctor.js +96 -0
- package/dist/core/securityDoctor.js.map +1 -0
- package/dist/core/skill.d.ts +16 -0
- package/dist/core/skill.js +81 -0
- package/dist/core/skill.js.map +1 -0
- package/dist/core/storage.d.ts +20 -0
- package/dist/core/storage.js +112 -0
- package/dist/core/storage.js.map +1 -0
- package/dist/core/tokens.d.ts +5 -0
- package/dist/core/tokens.js +24 -0
- package/dist/core/tokens.js.map +1 -0
- package/dist/core/worker.d.ts +51 -0
- package/dist/core/worker.js +312 -0
- package/dist/core/worker.js.map +1 -0
- package/dist/core/workflow.d.ts +61 -0
- package/dist/core/workflow.js +308 -0
- package/dist/core/workflow.js.map +1 -0
- package/dist/core/workspace.d.ts +7 -0
- package/dist/core/workspace.js +214 -0
- package/dist/core/workspace.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/schemas/brief.d.ts +12 -0
- package/dist/schemas/brief.js +2 -0
- package/dist/schemas/brief.js.map +1 -0
- package/dist/schemas/eval.d.ts +96 -0
- package/dist/schemas/eval.js +30 -0
- package/dist/schemas/eval.js.map +1 -0
- package/dist/schemas/handoff.d.ts +33 -0
- package/dist/schemas/handoff.js +13 -0
- package/dist/schemas/handoff.js.map +1 -0
- package/dist/schemas/log.d.ts +51 -0
- package/dist/schemas/log.js +19 -0
- package/dist/schemas/log.js.map +1 -0
- package/dist/schemas/memory.d.ts +112 -0
- package/dist/schemas/memory.js +21 -0
- package/dist/schemas/memory.js.map +1 -0
- package/dist/schemas/memoryProposal.d.ts +181 -0
- package/dist/schemas/memoryProposal.js +46 -0
- package/dist/schemas/memoryProposal.js.map +1 -0
- package/dist/schemas/patch.d.ts +38 -0
- package/dist/schemas/patch.js +15 -0
- package/dist/schemas/patch.js.map +1 -0
- package/dist/schemas/project.d.ts +23 -0
- package/dist/schemas/project.js +8 -0
- package/dist/schemas/project.js.map +1 -0
- package/dist/schemas/skill.d.ts +26 -0
- package/dist/schemas/skill.js +9 -0
- package/dist/schemas/skill.js.map +1 -0
- package/dist/schemas/worker.d.ts +29 -0
- package/dist/schemas/worker.js +12 -0
- package/dist/schemas/worker.js.map +1 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/docs/codex-resume.md +13 -0
- package/docs/compatibility.md +49 -0
- package/docs/concept.md +13 -0
- package/docs/evals.md +18 -0
- package/docs/file-format.md +67 -0
- package/docs/handoff-briefs.md +9 -0
- package/docs/integrations/harnesses.md +74 -0
- package/docs/memory-lifecycle.md +23 -0
- package/docs/persistent-worker.md +15 -0
- package/docs/privacy-model.md +40 -0
- package/docs/quickstart.md +74 -0
- package/docs/release-checklist.md +68 -0
- package/docs/roadmap.md +33 -0
- package/docs/superpowers/plans/2026-06-08-briefops-oss-readiness.md +1272 -0
- package/docs/superpowers/plans/2026-06-08-codex-first-context-optimization.md +1176 -0
- package/docs/token-budget.md +63 -0
- package/examples/atlas-q/README.md +15 -0
- package/examples/codex-first-context/README.md +48 -0
- package/examples/codex-first-context/after-briefops-prime.md +40 -0
- package/examples/codex-first-context/before-manual-history-dump.md +18 -0
- package/examples/persistent-worker-demo/README.md +15 -0
- package/examples/persistent-worker-demo/after-codex-resume.md +17 -0
- package/examples/persistent-worker-demo/before-context-dump.md +5 -0
- package/examples/persistent-worker-demo/briefops-workspace/codex/prompts/resume_demo.md +29 -0
- package/examples/persistent-worker-demo/briefops-workspace/handoffs/handoff_demo.md +50 -0
- package/examples/persistent-worker-demo/briefops-workspace/logs/log_20260604_001.yaml +14 -0
- package/examples/persistent-worker-demo/briefops-workspace/logs/log_20260604_002.yaml +12 -0
- package/examples/persistent-worker-demo/briefops-workspace/memory/decisions.yaml +12 -0
- package/examples/persistent-worker-demo/briefops-workspace/memory/deprecated.yaml +1 -0
- package/examples/persistent-worker-demo/briefops-workspace/memory/facts.yaml +12 -0
- package/examples/persistent-worker-demo/briefops-workspace/memory/incidents.yaml +12 -0
- package/examples/persistent-worker-demo/briefops-workspace/memory/lessons.yaml +12 -0
- package/examples/persistent-worker-demo/briefops-workspace/memory-proposals/memprop_demo_001.memory-proposal.yaml +23 -0
- package/examples/persistent-worker-demo/briefops-workspace/projects/atlas-q.project.md +18 -0
- package/examples/persistent-worker-demo/briefops-workspace/skills/backtest-validation.skill.md +13 -0
- package/examples/persistent-worker-demo/briefops-workspace/skills/risk-review.skill.md +15 -0
- package/examples/persistent-worker-demo/briefops-workspace/workers/quant-reviewer.worker.yaml +12 -0
- package/examples/persistent-worker-demo/briefops-workspace/workers/summaries/quant-reviewer.summary.md +44 -0
- package/package.json +59 -0
- package/plugins/briefops-codex/.codex-plugin/plugin.json +39 -0
- package/plugins/briefops-codex/README.md +44 -0
- package/plugins/briefops-codex/skills/briefops-continue-worker/SKILL.md +22 -0
- package/plugins/briefops-codex/skills/briefops-finish-task/SKILL.md +22 -0
- package/plugins/briefops-codex/skills/briefops-prime-context/SKILL.md +24 -0
- package/plugins/briefops-codex/skills/briefops-review-memory/SKILL.md +27 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { promises as fs } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { readBriefOpsConfig } from "./config.js";
|
|
4
|
+
import { listMemory } from "./memory.js";
|
|
5
|
+
import { listMemoryProposals } from "./memoryProposal.js";
|
|
6
|
+
import { memoryCategories, memoryFilePath, workspacePaths } from "./paths.js";
|
|
7
|
+
import { listSkillPatches } from "./patch.js";
|
|
8
|
+
import { pathExists, readTextFile, readYamlFile } from "./storage.js";
|
|
9
|
+
import { readWorker } from "./worker.js";
|
|
10
|
+
import { memoryFileSchema } from "../schemas/memory.js";
|
|
11
|
+
function check(name, status, detail) {
|
|
12
|
+
return { name, status, detail };
|
|
13
|
+
}
|
|
14
|
+
async function listStaleLocks(cwd, staleMs) {
|
|
15
|
+
const lockDir = path.join(workspacePaths(cwd).root, ".locks");
|
|
16
|
+
if (!(await pathExists(lockDir))) {
|
|
17
|
+
return [];
|
|
18
|
+
}
|
|
19
|
+
const entries = await fs.readdir(lockDir);
|
|
20
|
+
const stale = [];
|
|
21
|
+
for (const entry of entries.filter((item) => item.endsWith(".lock"))) {
|
|
22
|
+
const filePath = path.join(lockDir, entry);
|
|
23
|
+
const raw = await readTextFile(filePath);
|
|
24
|
+
const createdAt = raw.match(/^created_at: (.+)$/m)?.[1]?.trim();
|
|
25
|
+
const created = createdAt ? Date.parse(createdAt) : Number.NaN;
|
|
26
|
+
if (Number.isNaN(created) || Date.now() - created > staleMs) {
|
|
27
|
+
stale.push(entry);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return stale;
|
|
31
|
+
}
|
|
32
|
+
export async function runSecurityDoctor(options = {}) {
|
|
33
|
+
const cwd = options.cwd ?? process.cwd();
|
|
34
|
+
const paths = workspacePaths(cwd);
|
|
35
|
+
const checks = [];
|
|
36
|
+
if (!(await pathExists(paths.root))) {
|
|
37
|
+
return {
|
|
38
|
+
ok: false,
|
|
39
|
+
checks: [check("Workspace", "fail", ".briefops workspace not found.")]
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
checks.push(check("Workspace", "ok", paths.root));
|
|
43
|
+
let config;
|
|
44
|
+
try {
|
|
45
|
+
config = await readBriefOpsConfig(cwd);
|
|
46
|
+
checks.push(check("Config YAML", "ok", paths.config));
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
checks.push(check("Config YAML", "fail", error instanceof Error ? error.message : String(error)));
|
|
50
|
+
}
|
|
51
|
+
const invalidMemory = [];
|
|
52
|
+
for (const category of memoryCategories) {
|
|
53
|
+
try {
|
|
54
|
+
await readYamlFile(memoryFilePath(cwd, category), memoryFileSchema, { items: [] });
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
invalidMemory.push(`${category}: ${error instanceof Error ? error.message : String(error)}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
checks.push(invalidMemory.length === 0
|
|
61
|
+
? check("Memory YAML", "ok", "All memory files are valid.")
|
|
62
|
+
: check("Memory YAML", "fail", invalidMemory.join("; ")));
|
|
63
|
+
if (config?.defaults.worker) {
|
|
64
|
+
try {
|
|
65
|
+
await readWorker(cwd, config.defaults.worker);
|
|
66
|
+
checks.push(check("Default worker", "ok", config.defaults.worker));
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
checks.push(check("Default worker", "fail", error instanceof Error ? error.message : String(error)));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
checks.push(check("Default worker", "warn", "No default worker selected."));
|
|
74
|
+
}
|
|
75
|
+
const pendingMemory = await listMemoryProposals({ cwd, status: "proposed" });
|
|
76
|
+
checks.push(pendingMemory.length > 0
|
|
77
|
+
? check("Pending memory proposals", "warn", `${pendingMemory.length} proposal(s) need review.`)
|
|
78
|
+
: check("Pending memory proposals", "ok", "No pending memory proposals."));
|
|
79
|
+
const pendingPatches = (await listSkillPatches(cwd)).filter((patch) => patch.status === "proposed");
|
|
80
|
+
checks.push(pendingPatches.length > 0
|
|
81
|
+
? check("Pending skill patches", "warn", `${pendingPatches.length} patch(es) need review.`)
|
|
82
|
+
: check("Pending skill patches", "ok", "No pending skill patches."));
|
|
83
|
+
const privateExportable = (await listMemory({ cwd })).filter((item) => item.visibility === "private" && item.exportable);
|
|
84
|
+
checks.push(privateExportable.length > 0
|
|
85
|
+
? check("Private exportable memory", "warn", `${privateExportable.length} private item(s) are exportable.`)
|
|
86
|
+
: check("Private exportable memory", "ok", "No private exportable memory."));
|
|
87
|
+
const staleLocks = await listStaleLocks(cwd, options.staleMs ?? 30 * 60 * 1000);
|
|
88
|
+
checks.push(staleLocks.length > 0
|
|
89
|
+
? check("Stale lock files", "fail", staleLocks.join(", "))
|
|
90
|
+
: check("Stale lock files", "ok", "No stale lock files."));
|
|
91
|
+
return {
|
|
92
|
+
ok: checks.every((item) => item.status !== "fail"),
|
|
93
|
+
checks
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=securityDoctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"securityDoctor.js","sourceRoot":"","sources":["../../src/core/securityDoctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type SkillDocument } from "../schemas/skill.js";
|
|
2
|
+
export type CreateSkillOptions = {
|
|
3
|
+
cwd?: string;
|
|
4
|
+
name: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
tags?: string[];
|
|
7
|
+
maxTokens?: number;
|
|
8
|
+
force?: boolean;
|
|
9
|
+
};
|
|
10
|
+
export declare function createSkill(options: CreateSkillOptions): Promise<{
|
|
11
|
+
path: string;
|
|
12
|
+
name: string;
|
|
13
|
+
}>;
|
|
14
|
+
export declare function readSkill(cwd: string, name: string): Promise<SkillDocument>;
|
|
15
|
+
export declare function showSkill(cwd: string, name: string): Promise<string>;
|
|
16
|
+
export declare function listSkills(cwd?: string): Promise<SkillDocument[]>;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { BriefOpsError } from "./errors.js";
|
|
2
|
+
import { normalizeName, skillFilePath, workspacePaths } from "./paths.js";
|
|
3
|
+
import { listFilesBySuffix, parseMarkdownWithFrontmatter, readTextFile, stringifyMarkdownWithFrontmatter, writeTextFile } from "./storage.js";
|
|
4
|
+
import { requireWorkspace } from "./workspace.js";
|
|
5
|
+
import { skillFrontmatterSchema } from "../schemas/skill.js";
|
|
6
|
+
export async function createSkill(options) {
|
|
7
|
+
const cwd = options.cwd ?? process.cwd();
|
|
8
|
+
await requireWorkspace(cwd);
|
|
9
|
+
const name = normalizeName(options.name);
|
|
10
|
+
const filePath = skillFilePath(cwd, name);
|
|
11
|
+
const data = skillFrontmatterSchema.parse({
|
|
12
|
+
name,
|
|
13
|
+
version: "0.1.0",
|
|
14
|
+
description: options.description ?? "",
|
|
15
|
+
max_tokens: options.maxTokens ?? 700,
|
|
16
|
+
tags: options.tags ?? []
|
|
17
|
+
});
|
|
18
|
+
const body = [
|
|
19
|
+
`# Skill: ${name}`,
|
|
20
|
+
"",
|
|
21
|
+
"## Purpose",
|
|
22
|
+
"",
|
|
23
|
+
options.description || "Describe when and how this skill should be used.",
|
|
24
|
+
"",
|
|
25
|
+
"## Check",
|
|
26
|
+
"",
|
|
27
|
+
"- Add concrete checks this skill should perform.",
|
|
28
|
+
"",
|
|
29
|
+
"## Reject if",
|
|
30
|
+
"",
|
|
31
|
+
"- Add conditions that should block the work.",
|
|
32
|
+
"",
|
|
33
|
+
"## Output",
|
|
34
|
+
"",
|
|
35
|
+
"1. Summary",
|
|
36
|
+
"2. Findings or implementation notes",
|
|
37
|
+
"3. Required fixes",
|
|
38
|
+
"4. Verification performed"
|
|
39
|
+
].join("\n");
|
|
40
|
+
await writeTextFile(filePath, stringifyMarkdownWithFrontmatter(data, body), {
|
|
41
|
+
force: options.force
|
|
42
|
+
});
|
|
43
|
+
return { path: filePath, name };
|
|
44
|
+
}
|
|
45
|
+
export async function readSkill(cwd, name) {
|
|
46
|
+
await requireWorkspace(cwd);
|
|
47
|
+
const normalized = normalizeName(name);
|
|
48
|
+
const filePath = skillFilePath(cwd, normalized);
|
|
49
|
+
try {
|
|
50
|
+
const raw = await readTextFile(filePath);
|
|
51
|
+
return parseMarkdownWithFrontmatter(raw, skillFrontmatterSchema, filePath);
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
if (error instanceof BriefOpsError && error.message.startsWith("File not found")) {
|
|
55
|
+
throw new BriefOpsError(`Skill not found: ${normalized}`);
|
|
56
|
+
}
|
|
57
|
+
throw error;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
export async function showSkill(cwd, name) {
|
|
61
|
+
await requireWorkspace(cwd);
|
|
62
|
+
const normalized = normalizeName(name);
|
|
63
|
+
try {
|
|
64
|
+
return await readTextFile(skillFilePath(cwd, normalized));
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
if (error instanceof BriefOpsError && error.message.startsWith("File not found")) {
|
|
68
|
+
throw new BriefOpsError(`Skill not found: ${normalized}`);
|
|
69
|
+
}
|
|
70
|
+
throw error;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
export async function listSkills(cwd = process.cwd()) {
|
|
74
|
+
await requireWorkspace(cwd);
|
|
75
|
+
const files = await listFilesBySuffix(workspacePaths(cwd).skills, ".skill.md");
|
|
76
|
+
return Promise.all(files.map(async (filePath) => {
|
|
77
|
+
const raw = await readTextFile(filePath);
|
|
78
|
+
return parseMarkdownWithFrontmatter(raw, skillFrontmatterSchema, filePath);
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=skill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill.js","sourceRoot":"","sources":["../../src/core/skill.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare function pathExists(filePath: string): Promise<boolean>;
|
|
3
|
+
export declare function ensureDirectory(dirPath: string): Promise<void>;
|
|
4
|
+
export declare function writeFileIfAbsent(filePath: string, content: string): Promise<boolean>;
|
|
5
|
+
export declare function writeTextFile(filePath: string, content: string, options?: {
|
|
6
|
+
force?: boolean;
|
|
7
|
+
}): Promise<void>;
|
|
8
|
+
export declare function writeTextFileAtomic(filePath: string, content: string): Promise<void>;
|
|
9
|
+
export declare function readTextFile(filePath: string): Promise<string>;
|
|
10
|
+
export declare function readYamlFile<TSchema extends z.ZodTypeAny>(filePath: string, schema: TSchema, fallback: z.input<TSchema>): Promise<z.output<TSchema>>;
|
|
11
|
+
export declare function writeYamlFile(filePath: string, value: unknown): Promise<void>;
|
|
12
|
+
export declare function writeYamlFileAtomic(filePath: string, value: unknown): Promise<void>;
|
|
13
|
+
export declare function stringifyMarkdownWithFrontmatter(data: unknown, body: string): string;
|
|
14
|
+
export declare function parseMarkdownWithFrontmatter<TSchema extends z.ZodTypeAny>(raw: string, schema: TSchema, sourceName: string): {
|
|
15
|
+
data: z.output<TSchema>;
|
|
16
|
+
body: string;
|
|
17
|
+
raw: string;
|
|
18
|
+
};
|
|
19
|
+
export declare function listFilesBySuffix(dirPath: string, suffix: string): Promise<string[]>;
|
|
20
|
+
export declare function parseCommaList(value?: string): string[];
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { promises as fs } from "node:fs";
|
|
2
|
+
import { randomBytes } from "node:crypto";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import YAML from "yaml";
|
|
5
|
+
import { BriefOpsError } from "./errors.js";
|
|
6
|
+
export async function pathExists(filePath) {
|
|
7
|
+
try {
|
|
8
|
+
await fs.access(filePath);
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export async function ensureDirectory(dirPath) {
|
|
16
|
+
await fs.mkdir(dirPath, { recursive: true });
|
|
17
|
+
}
|
|
18
|
+
export async function writeFileIfAbsent(filePath, content) {
|
|
19
|
+
if (await pathExists(filePath)) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
await ensureDirectory(path.dirname(filePath));
|
|
23
|
+
await fs.writeFile(filePath, content, "utf8");
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
export async function writeTextFile(filePath, content, options = {}) {
|
|
27
|
+
if (!options.force && (await pathExists(filePath))) {
|
|
28
|
+
throw new BriefOpsError(`File already exists: ${filePath}`);
|
|
29
|
+
}
|
|
30
|
+
await ensureDirectory(path.dirname(filePath));
|
|
31
|
+
await writeTextFileAtomic(filePath, content);
|
|
32
|
+
}
|
|
33
|
+
export async function writeTextFileAtomic(filePath, content) {
|
|
34
|
+
await ensureDirectory(path.dirname(filePath));
|
|
35
|
+
const tempPath = path.join(path.dirname(filePath), `.tmp-${path.basename(filePath)}-${process.pid}-${randomBytes(4).toString("hex")}`);
|
|
36
|
+
try {
|
|
37
|
+
await fs.writeFile(tempPath, content, "utf8");
|
|
38
|
+
await fs.rename(tempPath, filePath);
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
await fs.unlink(tempPath).catch(() => undefined);
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export async function readTextFile(filePath) {
|
|
46
|
+
try {
|
|
47
|
+
return await fs.readFile(filePath, "utf8");
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
if (error.code === "ENOENT") {
|
|
51
|
+
throw new BriefOpsError(`File not found: ${filePath}`);
|
|
52
|
+
}
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export async function readYamlFile(filePath, schema, fallback) {
|
|
57
|
+
if (!(await pathExists(filePath))) {
|
|
58
|
+
return schema.parse(fallback);
|
|
59
|
+
}
|
|
60
|
+
const raw = await readTextFile(filePath);
|
|
61
|
+
const parsed = YAML.parse(raw) ?? fallback;
|
|
62
|
+
const result = schema.safeParse(parsed);
|
|
63
|
+
if (!result.success) {
|
|
64
|
+
throw new BriefOpsError(`Invalid YAML in ${filePath}: ${result.error.message}`);
|
|
65
|
+
}
|
|
66
|
+
return result.data;
|
|
67
|
+
}
|
|
68
|
+
export async function writeYamlFile(filePath, value) {
|
|
69
|
+
await writeYamlFileAtomic(filePath, value);
|
|
70
|
+
}
|
|
71
|
+
export async function writeYamlFileAtomic(filePath, value) {
|
|
72
|
+
await writeTextFileAtomic(filePath, `${YAML.stringify(value).trim()}\n`);
|
|
73
|
+
}
|
|
74
|
+
export function stringifyMarkdownWithFrontmatter(data, body) {
|
|
75
|
+
return `---\n${YAML.stringify(data).trim()}\n---\n\n${body.trim()}\n`;
|
|
76
|
+
}
|
|
77
|
+
export function parseMarkdownWithFrontmatter(raw, schema, sourceName) {
|
|
78
|
+
const match = raw.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/);
|
|
79
|
+
if (!match) {
|
|
80
|
+
throw new BriefOpsError(`Missing frontmatter in ${sourceName}`);
|
|
81
|
+
}
|
|
82
|
+
const parsed = YAML.parse(match[1] ?? "") ?? {};
|
|
83
|
+
const result = schema.safeParse(parsed);
|
|
84
|
+
if (!result.success) {
|
|
85
|
+
throw new BriefOpsError(`Invalid frontmatter in ${sourceName}: ${result.error.message}`);
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
data: result.data,
|
|
89
|
+
body: (match[2] ?? "").trim(),
|
|
90
|
+
raw
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
export async function listFilesBySuffix(dirPath, suffix) {
|
|
94
|
+
if (!(await pathExists(dirPath))) {
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
97
|
+
const entries = await fs.readdir(dirPath);
|
|
98
|
+
return entries
|
|
99
|
+
.filter((entry) => entry.endsWith(suffix))
|
|
100
|
+
.sort()
|
|
101
|
+
.map((entry) => path.join(dirPath, entry));
|
|
102
|
+
}
|
|
103
|
+
export function parseCommaList(value) {
|
|
104
|
+
if (!value) {
|
|
105
|
+
return [];
|
|
106
|
+
}
|
|
107
|
+
return value
|
|
108
|
+
.split(",")
|
|
109
|
+
.map((item) => item.trim())
|
|
110
|
+
.filter(Boolean);
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/core/storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export function estimateTokens(value) {
|
|
2
|
+
if (value.length === 0) {
|
|
3
|
+
return 0;
|
|
4
|
+
}
|
|
5
|
+
return Math.ceil(value.length / 4);
|
|
6
|
+
}
|
|
7
|
+
export function truncateToTokenBudget(value, maxTokens) {
|
|
8
|
+
if (maxTokens <= 0) {
|
|
9
|
+
return { text: "", trimmed: value.length > 0 };
|
|
10
|
+
}
|
|
11
|
+
if (estimateTokens(value) <= maxTokens) {
|
|
12
|
+
return { text: value, trimmed: false };
|
|
13
|
+
}
|
|
14
|
+
const suffix = "\n\n[Trimmed to fit token budget.]";
|
|
15
|
+
const maxChars = Math.max(1, maxTokens * 4 - suffix.length);
|
|
16
|
+
const slice = value.slice(0, maxChars);
|
|
17
|
+
const boundary = slice.lastIndexOf("\n") > 80 ? slice.lastIndexOf("\n") : slice.lastIndexOf(" ");
|
|
18
|
+
const trimmed = slice.slice(0, boundary > 40 ? boundary : maxChars).trimEnd();
|
|
19
|
+
return {
|
|
20
|
+
text: `${trimmed}${suffix}`,
|
|
21
|
+
trimmed: true
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=tokens.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../src/core/tokens.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,CAAC;IACX,CAAC;IAED,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,KAAa,EACb,SAAiB;IAEjB,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;QACnB,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;IACjD,CAAC;IAED,IAAI,cAAc,CAAC,KAAK,CAAC,IAAI,SAAS,EAAE,CAAC;QACvC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IACzC,CAAC;IAED,MAAM,MAAM,GAAG,oCAAoC,CAAC;IACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5D,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IACvC,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACjG,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,GAAG,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAC;IAE9E,OAAO;QACL,IAAI,EAAE,GAAG,OAAO,GAAG,MAAM,EAAE;QAC3B,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { type WorkerProfile } from "../schemas/worker.js";
|
|
2
|
+
export type CreateWorkerOptions = {
|
|
3
|
+
cwd?: string;
|
|
4
|
+
name: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
project?: string;
|
|
7
|
+
skills?: string[] | string;
|
|
8
|
+
style?: string[] | string;
|
|
9
|
+
maxTokens?: number;
|
|
10
|
+
force?: boolean;
|
|
11
|
+
};
|
|
12
|
+
export type ListWorkerFilters = {
|
|
13
|
+
cwd?: string;
|
|
14
|
+
status?: string;
|
|
15
|
+
};
|
|
16
|
+
export declare function createWorker(options: CreateWorkerOptions): Promise<{
|
|
17
|
+
path: string;
|
|
18
|
+
worker: WorkerProfile;
|
|
19
|
+
}>;
|
|
20
|
+
export declare function readWorker(cwd: string, name: string): Promise<WorkerProfile>;
|
|
21
|
+
export declare function showWorker(cwd: string, name: string): Promise<string>;
|
|
22
|
+
export declare function listWorkers(filters?: ListWorkerFilters): Promise<WorkerProfile[]>;
|
|
23
|
+
export declare function summarizeWorker(cwd: string, name: string, limit?: number): Promise<string>;
|
|
24
|
+
export declare function refreshWorkerSummary(options: {
|
|
25
|
+
cwd?: string;
|
|
26
|
+
name: string;
|
|
27
|
+
limit?: number;
|
|
28
|
+
}): Promise<{
|
|
29
|
+
path: string;
|
|
30
|
+
content: string;
|
|
31
|
+
tokens: number;
|
|
32
|
+
}>;
|
|
33
|
+
export declare function refreshWorkerSummaryUnlocked(options: {
|
|
34
|
+
cwd?: string;
|
|
35
|
+
name: string;
|
|
36
|
+
limit?: number;
|
|
37
|
+
}): Promise<{
|
|
38
|
+
path: string;
|
|
39
|
+
content: string;
|
|
40
|
+
tokens: number;
|
|
41
|
+
}>;
|
|
42
|
+
export declare function generateWorkerIntelligence(options: {
|
|
43
|
+
cwd?: string;
|
|
44
|
+
name: string;
|
|
45
|
+
budget?: number;
|
|
46
|
+
}): Promise<{
|
|
47
|
+
content: string;
|
|
48
|
+
tokens: number;
|
|
49
|
+
}>;
|
|
50
|
+
export declare function readWorkerSummary(cwd: string, name: string): Promise<string | undefined>;
|
|
51
|
+
export declare function formatWorkerForBrief(cwd: string, name: string): Promise<string>;
|