@moreih29/nexus-core 0.11.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -63
- package/assets/agents/architect/body.ko.md +177 -0
- package/{agents → assets/agents}/architect/body.md +16 -0
- package/assets/agents/designer/body.ko.md +125 -0
- package/{agents → assets/agents}/designer/body.md +16 -0
- package/assets/agents/engineer/body.ko.md +106 -0
- package/{agents → assets/agents}/engineer/body.md +14 -0
- package/assets/agents/lead/body.ko.md +70 -0
- package/assets/agents/lead/body.md +70 -0
- package/assets/agents/postdoc/body.ko.md +122 -0
- package/{agents → assets/agents}/postdoc/body.md +16 -0
- package/assets/agents/researcher/body.ko.md +137 -0
- package/{agents → assets/agents}/researcher/body.md +15 -0
- package/assets/agents/reviewer/body.ko.md +138 -0
- package/{agents → assets/agents}/reviewer/body.md +15 -0
- package/assets/agents/strategist/body.ko.md +116 -0
- package/{agents → assets/agents}/strategist/body.md +16 -0
- package/assets/agents/tester/body.ko.md +195 -0
- package/{agents → assets/agents}/tester/body.md +15 -0
- package/assets/agents/writer/body.ko.md +122 -0
- package/{agents → assets/agents}/writer/body.md +14 -0
- package/assets/capability-matrix.yml +198 -0
- package/assets/hooks/agent-bootstrap/handler.test.ts +368 -0
- package/assets/hooks/agent-bootstrap/handler.ts +119 -0
- package/assets/hooks/agent-bootstrap/meta.yml +10 -0
- package/assets/hooks/agent-finalize/handler.test.ts +368 -0
- package/assets/hooks/agent-finalize/handler.ts +76 -0
- package/assets/hooks/agent-finalize/meta.yml +10 -0
- package/assets/hooks/capability-matrix.yml +313 -0
- package/assets/hooks/post-tool-telemetry/handler.test.ts +302 -0
- package/assets/hooks/post-tool-telemetry/handler.ts +49 -0
- package/assets/hooks/post-tool-telemetry/meta.yml +11 -0
- package/assets/hooks/prompt-router/handler.test.ts +801 -0
- package/assets/hooks/prompt-router/handler.ts +261 -0
- package/assets/hooks/prompt-router/meta.yml +11 -0
- package/assets/hooks/session-init/handler.test.ts +274 -0
- package/assets/hooks/session-init/handler.ts +30 -0
- package/assets/hooks/session-init/meta.yml +9 -0
- package/assets/lsp-servers.json +55 -0
- package/assets/schema/lsp-servers.schema.json +67 -0
- package/assets/skills/nx-init/body.ko.md +197 -0
- package/{skills → assets/skills}/nx-init/body.md +11 -0
- package/assets/skills/nx-plan/body.ko.md +361 -0
- package/{skills → assets/skills}/nx-plan/body.md +13 -0
- package/assets/skills/nx-run/body.ko.md +161 -0
- package/{skills → assets/skills}/nx-run/body.md +11 -0
- package/assets/skills/nx-sync/body.ko.md +92 -0
- package/{skills → assets/skills}/nx-sync/body.md +10 -0
- package/assets/tools/tool-name-map.yml +353 -0
- package/dist/hooks/opencode-mount.d.ts +35 -0
- package/dist/hooks/opencode-mount.d.ts.map +1 -0
- package/dist/hooks/opencode-mount.js +332 -0
- package/dist/hooks/opencode-mount.js.map +1 -0
- package/dist/hooks/runtime.d.ts +37 -0
- package/dist/hooks/runtime.d.ts.map +1 -0
- package/dist/hooks/runtime.js +274 -0
- package/dist/hooks/runtime.js.map +1 -0
- package/dist/hooks/types.d.ts +196 -0
- package/dist/hooks/types.d.ts.map +1 -0
- package/dist/hooks/types.js +85 -0
- package/dist/hooks/types.js.map +1 -0
- package/dist/lsp/cache.d.ts +9 -0
- package/dist/lsp/cache.d.ts.map +1 -0
- package/dist/lsp/cache.js +216 -0
- package/dist/lsp/cache.js.map +1 -0
- package/dist/lsp/client.d.ts +24 -0
- package/dist/lsp/client.d.ts.map +1 -0
- package/dist/lsp/client.js +166 -0
- package/dist/lsp/client.js.map +1 -0
- package/dist/lsp/detect.d.ts +77 -0
- package/dist/lsp/detect.d.ts.map +1 -0
- package/dist/lsp/detect.js +116 -0
- package/dist/lsp/detect.js.map +1 -0
- package/dist/mcp/server.d.ts +5 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +34 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools/artifact.d.ts +4 -0
- package/dist/mcp/tools/artifact.d.ts.map +1 -0
- package/dist/mcp/tools/artifact.js +36 -0
- package/dist/mcp/tools/artifact.js.map +1 -0
- package/dist/mcp/tools/history.d.ts +3 -0
- package/dist/mcp/tools/history.d.ts.map +1 -0
- package/dist/mcp/tools/history.js +29 -0
- package/dist/mcp/tools/history.js.map +1 -0
- package/dist/mcp/tools/lsp.d.ts +13 -0
- package/dist/mcp/tools/lsp.d.ts.map +1 -0
- package/dist/mcp/tools/lsp.js +225 -0
- package/dist/mcp/tools/lsp.js.map +1 -0
- package/dist/mcp/tools/plan.d.ts +3 -0
- package/dist/mcp/tools/plan.d.ts.map +1 -0
- package/dist/mcp/tools/plan.js +317 -0
- package/dist/mcp/tools/plan.js.map +1 -0
- package/dist/mcp/tools/task.d.ts +3 -0
- package/dist/mcp/tools/task.d.ts.map +1 -0
- package/dist/mcp/tools/task.js +252 -0
- package/dist/mcp/tools/task.js.map +1 -0
- package/dist/shared/invocations.d.ts +74 -0
- package/dist/shared/invocations.d.ts.map +1 -0
- package/dist/shared/invocations.js +247 -0
- package/dist/shared/invocations.js.map +1 -0
- package/dist/shared/json-store.d.ts +37 -0
- package/dist/shared/json-store.d.ts.map +1 -0
- package/dist/shared/json-store.js +163 -0
- package/dist/shared/json-store.js.map +1 -0
- package/dist/shared/mcp-utils.d.ts +3 -0
- package/dist/shared/mcp-utils.d.ts.map +1 -0
- package/dist/shared/mcp-utils.js +6 -0
- package/dist/shared/mcp-utils.js.map +1 -0
- package/dist/shared/paths.d.ts +21 -0
- package/dist/shared/paths.d.ts.map +1 -0
- package/dist/shared/paths.js +81 -0
- package/dist/shared/paths.js.map +1 -0
- package/dist/shared/tool-log.d.ts +8 -0
- package/dist/shared/tool-log.d.ts.map +1 -0
- package/dist/shared/tool-log.js +22 -0
- package/dist/shared/tool-log.js.map +1 -0
- package/dist/types/state.d.ts +862 -0
- package/dist/types/state.d.ts.map +1 -0
- package/dist/types/state.js +66 -0
- package/dist/types/state.js.map +1 -0
- package/docs/consuming/codex-lead-merge.md +106 -0
- package/docs/plugin-guide.md +360 -0
- package/docs/plugin-template/claude/.github/workflows/build.yml +60 -0
- package/docs/plugin-template/claude/README.md +110 -0
- package/docs/plugin-template/claude/package.json +16 -0
- package/docs/plugin-template/codex/.github/workflows/build.yml +51 -0
- package/docs/plugin-template/codex/README.md +147 -0
- package/docs/plugin-template/codex/package.json +17 -0
- package/docs/plugin-template/opencode/.github/workflows/build.yml +61 -0
- package/docs/plugin-template/opencode/README.md +121 -0
- package/docs/plugin-template/opencode/package.json +25 -0
- package/package.json +21 -21
- package/scripts/build-agents.test.ts +1279 -0
- package/scripts/build-agents.ts +978 -0
- package/scripts/build-hooks.test.ts +1385 -0
- package/scripts/build-hooks.ts +584 -0
- package/scripts/cli.test.ts +367 -0
- package/scripts/cli.ts +547 -0
- package/agents/architect/meta.yml +0 -13
- package/agents/designer/meta.yml +0 -13
- package/agents/engineer/meta.yml +0 -11
- package/agents/postdoc/meta.yml +0 -13
- package/agents/researcher/meta.yml +0 -12
- package/agents/reviewer/meta.yml +0 -12
- package/agents/strategist/meta.yml +0 -13
- package/agents/tester/meta.yml +0 -12
- package/agents/writer/meta.yml +0 -11
- package/conformance/README.md +0 -311
- package/conformance/examples/plan.extension.schema.example.json +0 -25
- package/conformance/lifecycle/README.md +0 -48
- package/conformance/lifecycle/agent-complete.json +0 -44
- package/conformance/lifecycle/agent-resume.json +0 -43
- package/conformance/lifecycle/agent-spawn.json +0 -36
- package/conformance/lifecycle/memory-access-record.json +0 -27
- package/conformance/lifecycle/session-end.json +0 -48
- package/conformance/scenarios/full-plan-cycle.json +0 -147
- package/conformance/scenarios/task-deps-ordering.json +0 -95
- package/conformance/schema/fixture.schema.json +0 -354
- package/conformance/state-schemas/agent-tracker.schema.json +0 -63
- package/conformance/state-schemas/history.schema.json +0 -134
- package/conformance/state-schemas/memory-access.schema.json +0 -36
- package/conformance/state-schemas/plan.schema.json +0 -77
- package/conformance/state-schemas/tasks.schema.json +0 -98
- package/conformance/tools/artifact-write.json +0 -97
- package/conformance/tools/context.json +0 -172
- package/conformance/tools/history-search.json +0 -219
- package/conformance/tools/plan-decide.json +0 -139
- package/conformance/tools/plan-start.json +0 -81
- package/conformance/tools/plan-status.json +0 -127
- package/conformance/tools/plan-update.json +0 -341
- package/conformance/tools/task-add.json +0 -156
- package/conformance/tools/task-close.json +0 -161
- package/conformance/tools/task-list.json +0 -177
- package/conformance/tools/task-update.json +0 -167
- package/docs/behavioral-contracts.md +0 -145
- package/docs/consumer-implementation-guide.md +0 -852
- package/docs/memory-lifecycle-contract.md +0 -119
- package/docs/nexus-layout.md +0 -224
- package/docs/nexus-outputs-contract.md +0 -344
- package/docs/nexus-state-overview.md +0 -170
- package/docs/nexus-tools-contract.md +0 -438
- package/manifest.json +0 -449
- package/schema/README.md +0 -69
- package/schema/agent.schema.json +0 -23
- package/schema/common.schema.json +0 -17
- package/schema/manifest.schema.json +0 -78
- package/schema/memory-policy.schema.json +0 -98
- package/schema/skill.schema.json +0 -54
- package/schema/task-exceptions.schema.json +0 -40
- package/schema/vocabulary.schema.json +0 -167
- package/scripts/.gitkeep +0 -0
- package/scripts/conformance-coverage.ts +0 -466
- package/scripts/import-from-claude-nexus.ts +0 -403
- package/scripts/lib/frontmatter.ts +0 -71
- package/scripts/lib/lint.ts +0 -348
- package/scripts/lib/structure.ts +0 -159
- package/scripts/lib/validate.ts +0 -794
- package/scripts/validate.ts +0 -90
- package/skills/nx-init/meta.yml +0 -8
- package/skills/nx-plan/meta.yml +0 -10
- package/skills/nx-run/meta.yml +0 -9
- package/skills/nx-sync/meta.yml +0 -7
- package/vocabulary/capabilities.yml +0 -65
- package/vocabulary/categories.yml +0 -11
- package/vocabulary/invocations.yml +0 -147
- package/vocabulary/memory_policy.yml +0 -88
- package/vocabulary/resume-tiers.yml +0 -11
- package/vocabulary/tags.yml +0 -60
- package/vocabulary/task-exceptions.yml +0 -29
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import { getNexusRoot, getSessionRoot, getCurrentBranch, ensureDir } from "../../shared/paths.js";
|
|
5
|
+
import { readJsonFile, updateJsonFileLocked } from "../../shared/json-store.js";
|
|
6
|
+
import { textResult } from "../../shared/mcp-utils.js";
|
|
7
|
+
import { logToolCall } from "../../shared/tool-log.js";
|
|
8
|
+
import { TaskOwnerSchema, ResumeTierSchema } from "../../types/state.js";
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// Internal helpers
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
function tasksPath() {
|
|
13
|
+
return join(getSessionRoot(), "tasks.json");
|
|
14
|
+
}
|
|
15
|
+
function planPath() {
|
|
16
|
+
return join(getSessionRoot(), "plan.json");
|
|
17
|
+
}
|
|
18
|
+
function historyPath() {
|
|
19
|
+
return join(getNexusRoot(), "history.json");
|
|
20
|
+
}
|
|
21
|
+
const defaultTasksFile = () => ({ tasks: [] });
|
|
22
|
+
// Compute summary partition over all tasks (mutually exclusive).
|
|
23
|
+
// - in_progress: status === "in_progress"
|
|
24
|
+
// - completed: status === "completed"
|
|
25
|
+
// - blocked: status === "pending" AND has at least one dep that is NOT completed
|
|
26
|
+
// - ready: status === "pending" AND all deps are completed (or no deps)
|
|
27
|
+
function computeSummary(tasks) {
|
|
28
|
+
const completedIds = new Set(tasks.filter((t) => t.status === "completed").map((t) => t.id));
|
|
29
|
+
const in_progress = [];
|
|
30
|
+
const completed = [];
|
|
31
|
+
const blocked = [];
|
|
32
|
+
const ready = [];
|
|
33
|
+
for (const task of tasks) {
|
|
34
|
+
if (task.status === "in_progress") {
|
|
35
|
+
in_progress.push(task.id);
|
|
36
|
+
}
|
|
37
|
+
else if (task.status === "completed") {
|
|
38
|
+
completed.push(task.id);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
// pending
|
|
42
|
+
const deps = task.deps ?? [];
|
|
43
|
+
const allDepsComplete = deps.every((dep) => completedIds.has(dep));
|
|
44
|
+
if (allDepsComplete) {
|
|
45
|
+
ready.push(task.id);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
blocked.push(task.id);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return { total: tasks.length, in_progress, completed, blocked, ready };
|
|
53
|
+
}
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
// registerTaskTools
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
export function registerTaskTools(server) {
|
|
58
|
+
// -----------------------------------------------------------------------
|
|
59
|
+
// nx_task_add
|
|
60
|
+
// -----------------------------------------------------------------------
|
|
61
|
+
server.tool("nx_task_add", "새 task 추가 — tasks.json에 TaskItem 삽입", {
|
|
62
|
+
title: z.string().describe("Task 제목"),
|
|
63
|
+
context: z.string().describe("Task 컨텍스트 설명"),
|
|
64
|
+
acceptance: z.string().describe("완료 조건 (DoD) — 필수"),
|
|
65
|
+
approach: z.string().optional().describe("구현 접근법"),
|
|
66
|
+
risk: z.string().optional().describe("알려진 리스크"),
|
|
67
|
+
plan_issue: z.number().optional().describe("연관 plan issue ID"),
|
|
68
|
+
deps: z.array(z.number()).optional().describe("선행 task ID 목록"),
|
|
69
|
+
owner: TaskOwnerSchema.describe("소유자 정보 (role 필수)"),
|
|
70
|
+
goal: z.string().optional().describe("tasks.json top-level goal 갱신"),
|
|
71
|
+
decisions: z.array(z.string()).optional().describe("tasks.json top-level decisions append"),
|
|
72
|
+
}, async ({ title, context, acceptance, approach, risk, plan_issue, deps, owner, goal, decisions }) => {
|
|
73
|
+
const t0 = Date.now();
|
|
74
|
+
const tPath = tasksPath();
|
|
75
|
+
let newTask;
|
|
76
|
+
await updateJsonFileLocked(tPath, defaultTasksFile(), (data) => {
|
|
77
|
+
if (goal !== undefined) {
|
|
78
|
+
data.goal = goal;
|
|
79
|
+
}
|
|
80
|
+
if (decisions !== undefined && decisions.length > 0) {
|
|
81
|
+
data.decisions = [...(data.decisions ?? []), ...decisions];
|
|
82
|
+
}
|
|
83
|
+
// Validate deps
|
|
84
|
+
if (deps && deps.length > 0) {
|
|
85
|
+
const existingIds = new Set(data.tasks.map((t) => t.id));
|
|
86
|
+
for (let i = 0; i < deps.length; i++) {
|
|
87
|
+
if (!existingIds.has(deps[i])) {
|
|
88
|
+
throw new Error(`deps[${i}] does not exist: task id ${deps[i]} not found`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
const maxId = data.tasks.reduce((m, t) => Math.max(m, t.id), 0);
|
|
93
|
+
newTask = {
|
|
94
|
+
id: maxId + 1,
|
|
95
|
+
title,
|
|
96
|
+
status: "pending",
|
|
97
|
+
context,
|
|
98
|
+
acceptance,
|
|
99
|
+
...(approach !== undefined ? { approach } : {}),
|
|
100
|
+
...(risk !== undefined ? { risk } : {}),
|
|
101
|
+
...(plan_issue !== undefined ? { plan_issue } : {}),
|
|
102
|
+
...(deps !== undefined && deps.length > 0 ? { deps } : {}),
|
|
103
|
+
owner,
|
|
104
|
+
created_at: new Date().toISOString(),
|
|
105
|
+
};
|
|
106
|
+
data.tasks.push(newTask);
|
|
107
|
+
return data;
|
|
108
|
+
});
|
|
109
|
+
const response = { task: newTask };
|
|
110
|
+
logToolCall({ tool: "nx_task_add", args: { title, owner }, response, duration_ms: Date.now() - t0 });
|
|
111
|
+
return textResult(response);
|
|
112
|
+
});
|
|
113
|
+
// -----------------------------------------------------------------------
|
|
114
|
+
// nx_task_list
|
|
115
|
+
// -----------------------------------------------------------------------
|
|
116
|
+
server.tool("nx_task_list", "tasks.json 조회 — task 목록 및 summary 반환", {
|
|
117
|
+
include_completed: z.boolean().optional().describe("완료 task 포함 여부 (기본 true)"),
|
|
118
|
+
}, async ({ include_completed = true }) => {
|
|
119
|
+
const t0 = Date.now();
|
|
120
|
+
const data = await readJsonFile(tasksPath(), null);
|
|
121
|
+
if (!data) {
|
|
122
|
+
const response = { tasks: [], summary: { total: 0, in_progress: [], completed: [], blocked: [], ready: [] } };
|
|
123
|
+
logToolCall({ tool: "nx_task_list", args: { include_completed }, response, duration_ms: Date.now() - t0 });
|
|
124
|
+
return textResult(response);
|
|
125
|
+
}
|
|
126
|
+
// summary is always computed over ALL tasks regardless of include_completed
|
|
127
|
+
const summary = computeSummary(data.tasks);
|
|
128
|
+
const tasks = include_completed
|
|
129
|
+
? data.tasks
|
|
130
|
+
: data.tasks.filter((t) => t.status !== "completed");
|
|
131
|
+
const response = { tasks, summary };
|
|
132
|
+
if (data.goal !== undefined)
|
|
133
|
+
response.goal = data.goal;
|
|
134
|
+
logToolCall({ tool: "nx_task_list", args: { include_completed }, response, duration_ms: Date.now() - t0 });
|
|
135
|
+
return textResult(response);
|
|
136
|
+
});
|
|
137
|
+
// -----------------------------------------------------------------------
|
|
138
|
+
// nx_task_update
|
|
139
|
+
// -----------------------------------------------------------------------
|
|
140
|
+
// Update owner schema — role 갱신 불가, agent_id/resume_tier nullable
|
|
141
|
+
const TaskOwnerUpdateSchema = z.object({
|
|
142
|
+
agent_id: z.string().nullable().optional(),
|
|
143
|
+
resume_tier: ResumeTierSchema.nullable().optional(),
|
|
144
|
+
});
|
|
145
|
+
server.tool("nx_task_update", "Task status 또는 owner 메타데이터 부분 갱신", {
|
|
146
|
+
id: z.number().describe("갱신할 task ID"),
|
|
147
|
+
status: z.enum(["pending", "in_progress", "completed"]).optional().describe("새 상태"),
|
|
148
|
+
owner: TaskOwnerUpdateSchema.optional().describe("owner 부분 갱신 (agent_id, resume_tier만 — role 갱신 불가)"),
|
|
149
|
+
}, async ({ id, status, owner }) => {
|
|
150
|
+
const t0 = Date.now();
|
|
151
|
+
const tPath = tasksPath();
|
|
152
|
+
let updatedTask;
|
|
153
|
+
await updateJsonFileLocked(tPath, defaultTasksFile(), (data) => {
|
|
154
|
+
const task = data.tasks.find((t) => t.id === id);
|
|
155
|
+
if (!task)
|
|
156
|
+
throw new Error(`Task ${id} not found`);
|
|
157
|
+
if (status !== undefined) {
|
|
158
|
+
task.status = status;
|
|
159
|
+
}
|
|
160
|
+
if (owner !== undefined) {
|
|
161
|
+
if ("agent_id" in owner) {
|
|
162
|
+
const val = owner.agent_id;
|
|
163
|
+
if (val === null || val === "") {
|
|
164
|
+
delete task.owner.agent_id;
|
|
165
|
+
}
|
|
166
|
+
else if (val !== undefined) {
|
|
167
|
+
task.owner.agent_id = val;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
if ("resume_tier" in owner) {
|
|
171
|
+
const val = owner.resume_tier;
|
|
172
|
+
if (val === null) {
|
|
173
|
+
delete task.owner.resume_tier;
|
|
174
|
+
}
|
|
175
|
+
else if (val !== undefined) {
|
|
176
|
+
task.owner.resume_tier = val;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
updatedTask = task;
|
|
181
|
+
return data;
|
|
182
|
+
});
|
|
183
|
+
const response = { task: updatedTask };
|
|
184
|
+
logToolCall({ tool: "nx_task_update", args: { id, status }, response, duration_ms: Date.now() - t0 });
|
|
185
|
+
return textResult(response);
|
|
186
|
+
});
|
|
187
|
+
// -----------------------------------------------------------------------
|
|
188
|
+
// nx_task_close
|
|
189
|
+
// -----------------------------------------------------------------------
|
|
190
|
+
server.tool("nx_task_close", "현재 사이클 종료 — history.json에 아카이브 후 plan.json·tasks.json 삭제", {}, async () => {
|
|
191
|
+
const t0 = Date.now();
|
|
192
|
+
const tPath = tasksPath();
|
|
193
|
+
const pPath = planPath();
|
|
194
|
+
const hPath = historyPath();
|
|
195
|
+
const tasksData = await readJsonFile(tPath, null);
|
|
196
|
+
const planData = await readJsonFile(pPath, null);
|
|
197
|
+
const tasks = tasksData?.tasks ?? [];
|
|
198
|
+
const plan_id = planData?.id ?? null;
|
|
199
|
+
const task_count = tasks.length;
|
|
200
|
+
const incomplete_count = tasks.filter((t) => t.status !== "completed").length;
|
|
201
|
+
// Append to history.json
|
|
202
|
+
await updateJsonFileLocked(hPath, { cycles: [] }, (history) => {
|
|
203
|
+
history.cycles.push({
|
|
204
|
+
schema_version: "1.0",
|
|
205
|
+
completed_at: new Date().toISOString(),
|
|
206
|
+
branch: getCurrentBranch(),
|
|
207
|
+
...(planData ? { plan: planData } : {}),
|
|
208
|
+
tasks,
|
|
209
|
+
});
|
|
210
|
+
return history;
|
|
211
|
+
});
|
|
212
|
+
// Unlink plan.json and tasks.json
|
|
213
|
+
ensureDir(getNexusRoot());
|
|
214
|
+
try {
|
|
215
|
+
fs.unlinkSync(pPath);
|
|
216
|
+
}
|
|
217
|
+
catch { /* not present */ }
|
|
218
|
+
try {
|
|
219
|
+
fs.unlinkSync(tPath);
|
|
220
|
+
}
|
|
221
|
+
catch { /* not present */ }
|
|
222
|
+
const response = { closed: true, plan_id, task_count, incomplete_count };
|
|
223
|
+
logToolCall({ tool: "nx_task_close", args: {}, response, duration_ms: Date.now() - t0 });
|
|
224
|
+
return textResult(response);
|
|
225
|
+
});
|
|
226
|
+
// -----------------------------------------------------------------------
|
|
227
|
+
// nx_task_resume
|
|
228
|
+
// -----------------------------------------------------------------------
|
|
229
|
+
server.tool("nx_task_resume", "Task resume 라우팅 정보 조회 — owner.resume_tier 기반 정책 반환", {
|
|
230
|
+
id: z.number().describe("조회할 task ID"),
|
|
231
|
+
}, async ({ id }) => {
|
|
232
|
+
const t0 = Date.now();
|
|
233
|
+
const data = await readJsonFile(tasksPath(), null);
|
|
234
|
+
if (!data)
|
|
235
|
+
throw new Error(`Task ${id} not found`);
|
|
236
|
+
const task = data.tasks.find((t) => t.id === id);
|
|
237
|
+
if (!task)
|
|
238
|
+
throw new Error(`Task ${id} not found`);
|
|
239
|
+
const resumable = task.owner.resume_tier !== undefined && task.owner.resume_tier !== null;
|
|
240
|
+
const agent_id = task.owner.agent_id ?? null;
|
|
241
|
+
const resume_tier = task.owner.resume_tier ?? null;
|
|
242
|
+
const response = {
|
|
243
|
+
task_id: task.id,
|
|
244
|
+
resumable,
|
|
245
|
+
agent_id,
|
|
246
|
+
resume_tier,
|
|
247
|
+
};
|
|
248
|
+
logToolCall({ tool: "nx_task_resume", args: { id }, response, duration_ms: Date.now() - t0 });
|
|
249
|
+
return textResult(response);
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
//# sourceMappingURL=task.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task.js","sourceRoot":"","sources":["../../../src/mcp/tools/task.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/shared/invocations.ts
|
|
3
|
+
*
|
|
4
|
+
* expandInvocation — cross-harness invocation template expansion.
|
|
5
|
+
*
|
|
6
|
+
* Resolves {{template_name key=value ...}} placeholders in agent/skill body.md
|
|
7
|
+
* to harness-native call syntax as defined in assets/tools/tool-name-map.yml
|
|
8
|
+
* invocations section.
|
|
9
|
+
*
|
|
10
|
+
* Supported templates (4):
|
|
11
|
+
* {{subagent_spawn target_role=<role> prompt=<text> [name=<label>]}}
|
|
12
|
+
* {{skill_activation skill=<name> [mode=<mode>]}}
|
|
13
|
+
* {{task_register label=<text> state=<text>}}
|
|
14
|
+
* {{user_question question=<text> options=<json-array>}}
|
|
15
|
+
*/
|
|
16
|
+
export type Harness = "claude" | "opencode" | "codex";
|
|
17
|
+
export interface InvocationTemplate {
|
|
18
|
+
args: string[];
|
|
19
|
+
templates: Record<Harness, string>;
|
|
20
|
+
}
|
|
21
|
+
export interface InvocationsMap {
|
|
22
|
+
[name: string]: InvocationTemplate;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Parse a {{...}} invocation call string into its template name and key=value args.
|
|
26
|
+
*
|
|
27
|
+
* Format: {{template_name key1=value1 key2=value2 ...}}
|
|
28
|
+
* Values may be:
|
|
29
|
+
* - double-quoted strings: "..."
|
|
30
|
+
* - bracket-balanced arrays: [...]
|
|
31
|
+
* - brace-balanced objects: {...}
|
|
32
|
+
* - plain non-whitespace tokens
|
|
33
|
+
*
|
|
34
|
+
* Returns null if the format is invalid.
|
|
35
|
+
*/
|
|
36
|
+
export declare function parseInvocationCall(call: string): {
|
|
37
|
+
name: string;
|
|
38
|
+
args: Record<string, string>;
|
|
39
|
+
} | null;
|
|
40
|
+
/**
|
|
41
|
+
* Apply a single invocation template for the given harness.
|
|
42
|
+
*
|
|
43
|
+
* Substitutes {placeholder} tokens in the template string with arg values.
|
|
44
|
+
* Optional args (those not in the args map) are omitted along with their
|
|
45
|
+
* surrounding delimiters when absent.
|
|
46
|
+
*
|
|
47
|
+
* Returns the harness-native syntax string, or an error comment if the
|
|
48
|
+
* template name is unknown or a required arg is missing.
|
|
49
|
+
*/
|
|
50
|
+
export declare function applyTemplate(templateStr: string, args: Record<string, string>, templateDef: InvocationTemplate): string;
|
|
51
|
+
/**
|
|
52
|
+
* Expand a single {{...}} invocation expression to harness-native syntax.
|
|
53
|
+
*
|
|
54
|
+
* @param expression The content inside {{ }}, e.g. "subagent_spawn target_role=engineer prompt=Fix the bug"
|
|
55
|
+
* @param harness Target harness: "claude" | "opencode" | "codex"
|
|
56
|
+
* @param invocations Parsed invocations map from tool-name-map.yml
|
|
57
|
+
*
|
|
58
|
+
* Returns the expanded string, or a comment if unknown/invalid.
|
|
59
|
+
*/
|
|
60
|
+
export declare function expandInvocationExpression(expression: string, harness: Harness, invocations: InvocationsMap): string;
|
|
61
|
+
/**
|
|
62
|
+
* Expand all {{...}} invocation placeholders in a body string.
|
|
63
|
+
*
|
|
64
|
+
* Uses a balance-counter scanner so that nested `{}` inside argument values
|
|
65
|
+
* (e.g. options=[{label: "Set up"}]) are correctly included in the match.
|
|
66
|
+
*
|
|
67
|
+
* @param input Raw body.md content (may contain multiple {{}} blocks)
|
|
68
|
+
* @param harness Target harness
|
|
69
|
+
* @param invocations Parsed invocations map
|
|
70
|
+
*
|
|
71
|
+
* Returns the body with all {{}} templates replaced by harness-native syntax.
|
|
72
|
+
*/
|
|
73
|
+
export declare function expandInvocations(input: string, harness: Harness, invocations: InvocationsMap): string;
|
|
74
|
+
//# sourceMappingURL=invocations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invocations.d.ts","sourceRoot":"","sources":["../../src/shared/invocations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,MAAM,OAAO,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;AAEtD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,cAAc;IAC7B,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,CAAC;CACpC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B,GAAG,IAAI,CAmGP;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,WAAW,EAAE,kBAAkB,GAC9B,MAAM,CAgBR;AAED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,cAAc,GAC1B,MAAM,CAiBR;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,cAAc,GAC1B,MAAM,CAqDR"}
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/shared/invocations.ts
|
|
3
|
+
*
|
|
4
|
+
* expandInvocation — cross-harness invocation template expansion.
|
|
5
|
+
*
|
|
6
|
+
* Resolves {{template_name key=value ...}} placeholders in agent/skill body.md
|
|
7
|
+
* to harness-native call syntax as defined in assets/tools/tool-name-map.yml
|
|
8
|
+
* invocations section.
|
|
9
|
+
*
|
|
10
|
+
* Supported templates (4):
|
|
11
|
+
* {{subagent_spawn target_role=<role> prompt=<text> [name=<label>]}}
|
|
12
|
+
* {{skill_activation skill=<name> [mode=<mode>]}}
|
|
13
|
+
* {{task_register label=<text> state=<text>}}
|
|
14
|
+
* {{user_question question=<text> options=<json-array>}}
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Parse a {{...}} invocation call string into its template name and key=value args.
|
|
18
|
+
*
|
|
19
|
+
* Format: {{template_name key1=value1 key2=value2 ...}}
|
|
20
|
+
* Values may be:
|
|
21
|
+
* - double-quoted strings: "..."
|
|
22
|
+
* - bracket-balanced arrays: [...]
|
|
23
|
+
* - brace-balanced objects: {...}
|
|
24
|
+
* - plain non-whitespace tokens
|
|
25
|
+
*
|
|
26
|
+
* Returns null if the format is invalid.
|
|
27
|
+
*/
|
|
28
|
+
export function parseInvocationCall(call) {
|
|
29
|
+
// call is the content inside {{ }}
|
|
30
|
+
const trimmed = call.trim();
|
|
31
|
+
if (!trimmed)
|
|
32
|
+
return null;
|
|
33
|
+
// Extract template name (first token)
|
|
34
|
+
const firstSpace = trimmed.indexOf(" ");
|
|
35
|
+
const name = firstSpace === -1 ? trimmed : trimmed.slice(0, firstSpace);
|
|
36
|
+
const rest = firstSpace === -1 ? "" : trimmed.slice(firstSpace + 1).trim();
|
|
37
|
+
const args = {};
|
|
38
|
+
if (rest) {
|
|
39
|
+
// Manual tokenizer: scan for key=<value> pairs where <value> may contain
|
|
40
|
+
// nested brackets/braces or quoted strings.
|
|
41
|
+
let i = 0;
|
|
42
|
+
while (i < rest.length) {
|
|
43
|
+
// Skip whitespace
|
|
44
|
+
while (i < rest.length && /\s/.test(rest[i]))
|
|
45
|
+
i++;
|
|
46
|
+
if (i >= rest.length)
|
|
47
|
+
break;
|
|
48
|
+
// Read key (word chars up to '=')
|
|
49
|
+
const keyStart = i;
|
|
50
|
+
while (i < rest.length && /\w/.test(rest[i]))
|
|
51
|
+
i++;
|
|
52
|
+
if (i >= rest.length || rest[i] !== "=") {
|
|
53
|
+
// Not a valid key=value pair — skip this token
|
|
54
|
+
while (i < rest.length && !/\s/.test(rest[i]))
|
|
55
|
+
i++;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
const key = rest.slice(keyStart, i);
|
|
59
|
+
i++; // consume '='
|
|
60
|
+
if (i >= rest.length)
|
|
61
|
+
break;
|
|
62
|
+
// Read value: dispatch on first character
|
|
63
|
+
let value = "";
|
|
64
|
+
const ch = rest[i];
|
|
65
|
+
if (ch === '"') {
|
|
66
|
+
// Quoted string — scan to closing unescaped quote
|
|
67
|
+
i++; // consume opening quote
|
|
68
|
+
const start = i;
|
|
69
|
+
while (i < rest.length) {
|
|
70
|
+
if (rest[i] === "\\" && i + 1 < rest.length) {
|
|
71
|
+
i += 2; // skip escape sequence
|
|
72
|
+
}
|
|
73
|
+
else if (rest[i] === '"') {
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
i++;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
value = rest.slice(start, i).replace(/\\"/g, '"');
|
|
81
|
+
if (i < rest.length)
|
|
82
|
+
i++; // consume closing quote
|
|
83
|
+
}
|
|
84
|
+
else if (ch === "[" || ch === "{") {
|
|
85
|
+
// Bracket/brace balanced scan
|
|
86
|
+
const open = ch;
|
|
87
|
+
const close = open === "[" ? "]" : "}";
|
|
88
|
+
let depth = 0;
|
|
89
|
+
const start = i;
|
|
90
|
+
while (i < rest.length) {
|
|
91
|
+
const c = rest[i];
|
|
92
|
+
if (c === '"') {
|
|
93
|
+
// Skip quoted section inside array/object
|
|
94
|
+
i++;
|
|
95
|
+
while (i < rest.length) {
|
|
96
|
+
if (rest[i] === "\\" && i + 1 < rest.length) {
|
|
97
|
+
i += 2;
|
|
98
|
+
}
|
|
99
|
+
else if (rest[i] === '"') {
|
|
100
|
+
i++;
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
i++;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
if (c === open)
|
|
110
|
+
depth++;
|
|
111
|
+
else if (c === close) {
|
|
112
|
+
depth--;
|
|
113
|
+
if (depth === 0) {
|
|
114
|
+
i++; // consume closing bracket
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
i++;
|
|
119
|
+
}
|
|
120
|
+
value = rest.slice(start, i);
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
// Plain non-whitespace token
|
|
124
|
+
const start = i;
|
|
125
|
+
while (i < rest.length && !/\s/.test(rest[i]))
|
|
126
|
+
i++;
|
|
127
|
+
value = rest.slice(start, i);
|
|
128
|
+
}
|
|
129
|
+
if (key)
|
|
130
|
+
args[key] = value;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return { name, args };
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Apply a single invocation template for the given harness.
|
|
137
|
+
*
|
|
138
|
+
* Substitutes {placeholder} tokens in the template string with arg values.
|
|
139
|
+
* Optional args (those not in the args map) are omitted along with their
|
|
140
|
+
* surrounding delimiters when absent.
|
|
141
|
+
*
|
|
142
|
+
* Returns the harness-native syntax string, or an error comment if the
|
|
143
|
+
* template name is unknown or a required arg is missing.
|
|
144
|
+
*/
|
|
145
|
+
export function applyTemplate(templateStr, args, templateDef) {
|
|
146
|
+
let result = templateStr;
|
|
147
|
+
// Replace all {key} tokens with their values
|
|
148
|
+
for (const [key, value] of Object.entries(args)) {
|
|
149
|
+
result = result.replace(new RegExp(`\\{${key}\\}`, "g"), value);
|
|
150
|
+
}
|
|
151
|
+
// Remove any remaining optional placeholders that have no value
|
|
152
|
+
// Pattern: `, "description": "{name}"` or similar — strip the whole field segment
|
|
153
|
+
// We handle this by removing ", key: "{remaining_token}"" patterns
|
|
154
|
+
result = result.replace(/,?\s*\w+:\s*"\{[^}]+\}"/g, "");
|
|
155
|
+
// Also handle ", description: {name}" without quotes (less common but defensive)
|
|
156
|
+
result = result.replace(/,?\s*\w+:\s*\{[^}]+\}/g, "");
|
|
157
|
+
return result;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Expand a single {{...}} invocation expression to harness-native syntax.
|
|
161
|
+
*
|
|
162
|
+
* @param expression The content inside {{ }}, e.g. "subagent_spawn target_role=engineer prompt=Fix the bug"
|
|
163
|
+
* @param harness Target harness: "claude" | "opencode" | "codex"
|
|
164
|
+
* @param invocations Parsed invocations map from tool-name-map.yml
|
|
165
|
+
*
|
|
166
|
+
* Returns the expanded string, or a comment if unknown/invalid.
|
|
167
|
+
*/
|
|
168
|
+
export function expandInvocationExpression(expression, harness, invocations) {
|
|
169
|
+
const parsed = parseInvocationCall(expression);
|
|
170
|
+
if (!parsed) {
|
|
171
|
+
return `/* [nexus] invalid invocation: ${expression.trim()} */`;
|
|
172
|
+
}
|
|
173
|
+
const def = invocations[parsed.name];
|
|
174
|
+
if (!def) {
|
|
175
|
+
return `/* [nexus] unknown invocation: ${parsed.name} */`;
|
|
176
|
+
}
|
|
177
|
+
const templateStr = def.templates[harness];
|
|
178
|
+
if (!templateStr) {
|
|
179
|
+
return `/* [nexus] no template for harness ${harness}: ${parsed.name} */`;
|
|
180
|
+
}
|
|
181
|
+
return applyTemplate(templateStr, parsed.args, def);
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Expand all {{...}} invocation placeholders in a body string.
|
|
185
|
+
*
|
|
186
|
+
* Uses a balance-counter scanner so that nested `{}` inside argument values
|
|
187
|
+
* (e.g. options=[{label: "Set up"}]) are correctly included in the match.
|
|
188
|
+
*
|
|
189
|
+
* @param input Raw body.md content (may contain multiple {{}} blocks)
|
|
190
|
+
* @param harness Target harness
|
|
191
|
+
* @param invocations Parsed invocations map
|
|
192
|
+
*
|
|
193
|
+
* Returns the body with all {{}} templates replaced by harness-native syntax.
|
|
194
|
+
*/
|
|
195
|
+
export function expandInvocations(input, harness, invocations) {
|
|
196
|
+
let result = "";
|
|
197
|
+
let i = 0;
|
|
198
|
+
while (i < input.length) {
|
|
199
|
+
// Find the next '{{'
|
|
200
|
+
const openIdx = input.indexOf("{{", i);
|
|
201
|
+
if (openIdx === -1) {
|
|
202
|
+
result += input.slice(i);
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
205
|
+
// Append text before the '{{'
|
|
206
|
+
result += input.slice(i, openIdx);
|
|
207
|
+
i = openIdx + 2; // move past '{{'
|
|
208
|
+
// Scan forward with brace depth to find the matching '}}'
|
|
209
|
+
// We start after '{{', depth tracks inner '{' vs '}'
|
|
210
|
+
let depth = 0;
|
|
211
|
+
let innerStart = i;
|
|
212
|
+
let found = false;
|
|
213
|
+
while (i < input.length) {
|
|
214
|
+
if (input[i] === "{") {
|
|
215
|
+
depth++;
|
|
216
|
+
i++;
|
|
217
|
+
}
|
|
218
|
+
else if (input[i] === "}") {
|
|
219
|
+
if (depth === 0 && input[i + 1] === "}") {
|
|
220
|
+
// Found the closing '}}'
|
|
221
|
+
const inner = input.slice(innerStart, i);
|
|
222
|
+
result += expandInvocationExpression(inner, harness, invocations);
|
|
223
|
+
i += 2; // consume '}}'
|
|
224
|
+
found = true;
|
|
225
|
+
break;
|
|
226
|
+
}
|
|
227
|
+
else if (depth > 0) {
|
|
228
|
+
depth--;
|
|
229
|
+
i++;
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
// Single '}' with no matching depth — treat as literal
|
|
233
|
+
i++;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
i++;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
if (!found) {
|
|
241
|
+
// No closing '}}' — treat the '{{' as literal text
|
|
242
|
+
result += "{{" + input.slice(innerStart, i);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return result;
|
|
246
|
+
}
|
|
247
|
+
//# sourceMappingURL=invocations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invocations.js","sourceRoot":"","sources":["../../src/shared/invocations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read a JSON file, returning `defaultValue` when the file does not exist or
|
|
3
|
+
* its content cannot be parsed.
|
|
4
|
+
*/
|
|
5
|
+
export declare function readJsonFile<T>(filePath: string, defaultValue: T): Promise<T>;
|
|
6
|
+
/**
|
|
7
|
+
* Atomically write a JSON file.
|
|
8
|
+
* Writes to a unique temp file then renames to the target path.
|
|
9
|
+
* Parent directories are created automatically.
|
|
10
|
+
*/
|
|
11
|
+
export declare function writeJsonFile<T>(filePath: string, data: T): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Read-modify-write a JSON file under a two-layer lock.
|
|
14
|
+
*
|
|
15
|
+
* Layer 1 — in-process promise queue: serialises concurrent calls within the
|
|
16
|
+
* same Node/Bun process with zero overhead and no retry cost.
|
|
17
|
+
*
|
|
18
|
+
* Layer 2 — cross-process `.lock` file (O_EXCL): prevents data races between
|
|
19
|
+
* separate processes. Retries every 100 ms for up to 50 attempts (5 s total).
|
|
20
|
+
* Stale locks (mtime > 30 s) are forcibly removed before retry.
|
|
21
|
+
*
|
|
22
|
+
* The lock is always released even when `updater` throws.
|
|
23
|
+
*/
|
|
24
|
+
export declare function updateJsonFileLocked<T>(filePath: string, defaultValue: T, updater: (current: T) => T | Promise<T>): Promise<T>;
|
|
25
|
+
/**
|
|
26
|
+
* Append a single JSON record as one line to a `.jsonl` file.
|
|
27
|
+
*
|
|
28
|
+
* Uses the OS `write(2)` syscall via `appendFileSync`, which is atomic for
|
|
29
|
+
* writes up to ~4 KB on most POSIX filesystems. Lines exceeding that threshold
|
|
30
|
+
* trigger a `console.error` warning but are still written (best-effort).
|
|
31
|
+
*
|
|
32
|
+
* No lock is acquired — concurrent appenders are safe at the line level
|
|
33
|
+
* because each call is a single `write(2)` syscall.
|
|
34
|
+
* Parent directories are created automatically.
|
|
35
|
+
*/
|
|
36
|
+
export declare function appendJsonLine(filePath: string, record: unknown): void;
|
|
37
|
+
//# sourceMappingURL=json-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-store.d.ts","sourceRoot":"","sources":["../../src/shared/json-store.ts"],"names":[],"mappings":"AA0FA;;;GAGG;AACH,wBAAsB,YAAY,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAenF;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAK/E;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,oBAAoB,CAAC,CAAC,EAC1C,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,CAAC,EACf,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GACtC,OAAO,CAAC,CAAC,CAAC,CAYZ;AAQD;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAYtE"}
|