@ksm0709/context 0.1.0-next.1 → 0.2.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/dist/cli/index.js +1 -1
- package/dist/index.js +62 -26
- package/dist/omc/session-start-hook.js +44 -8
- package/dist/omx/index.mjs +86 -48
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
// src/index.ts
|
|
3
|
-
import { existsSync as
|
|
4
|
-
import { join as
|
|
3
|
+
import { existsSync as existsSync4, readFileSync as readFileSync2, statSync, unlinkSync } from "fs";
|
|
4
|
+
import { join as join4, dirname as dirname2 } from "path";
|
|
5
5
|
import { fileURLToPath } from "url";
|
|
6
6
|
|
|
7
7
|
// src/lib/context-dir.ts
|
|
@@ -19,13 +19,48 @@ function resolveContextDir(projectDir) {
|
|
|
19
19
|
return nextContextDir;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
// src/lib/project-root.ts
|
|
23
|
+
import { existsSync as existsSync2 } from "fs";
|
|
24
|
+
import { join as join2, dirname, resolve } from "path";
|
|
25
|
+
import { homedir } from "os";
|
|
26
|
+
function findGitRoot(startDir) {
|
|
27
|
+
let current = resolve(startDir);
|
|
28
|
+
while (true) {
|
|
29
|
+
if (existsSync2(join2(current, ".git"))) {
|
|
30
|
+
return current;
|
|
31
|
+
}
|
|
32
|
+
const parent = dirname(current);
|
|
33
|
+
if (parent === current) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
current = parent;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function resolveProjectPaths(startDir) {
|
|
40
|
+
const gitRoot = findGitRoot(startDir);
|
|
41
|
+
if (gitRoot) {
|
|
42
|
+
return {
|
|
43
|
+
contextParent: gitRoot,
|
|
44
|
+
agentsMdPath: join2(gitRoot, "AGENTS.md"),
|
|
45
|
+
claudeMdPath: join2(gitRoot, "CLAUDE.md")
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
const home = homedir();
|
|
49
|
+
const contextDir = join2(home, ".context");
|
|
50
|
+
return {
|
|
51
|
+
contextParent: home,
|
|
52
|
+
agentsMdPath: join2(contextDir, "AGENTS.md"),
|
|
53
|
+
claudeMdPath: join2(contextDir, "CLAUDE.md")
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
22
57
|
// src/lib/scaffold.ts
|
|
23
|
-
import { existsSync as
|
|
24
|
-
import { join as
|
|
58
|
+
import { existsSync as existsSync3, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
59
|
+
import { join as join3 } from "path";
|
|
25
60
|
// package.json
|
|
26
61
|
var package_default = {
|
|
27
62
|
name: "@ksm0709/context",
|
|
28
|
-
version: "0.
|
|
63
|
+
version: "0.2.0",
|
|
29
64
|
author: {
|
|
30
65
|
name: "TaehoKang",
|
|
31
66
|
email: "ksm07091@gmail.com"
|
|
@@ -397,21 +432,21 @@ var TEMPLATE_FILES = {
|
|
|
397
432
|
"work-complete.txt": DEFAULT_WORK_COMPLETE_TEMPLATE
|
|
398
433
|
};
|
|
399
434
|
function scaffoldIfNeeded(projectDir) {
|
|
400
|
-
const contextDir =
|
|
401
|
-
if (
|
|
435
|
+
const contextDir = join3(projectDir, resolveContextDir(projectDir));
|
|
436
|
+
if (existsSync3(contextDir)) {
|
|
402
437
|
return false;
|
|
403
438
|
}
|
|
404
439
|
try {
|
|
405
|
-
const templatesDir =
|
|
440
|
+
const templatesDir = join3(contextDir, "templates");
|
|
406
441
|
mkdirSync(templatesDir, { recursive: true });
|
|
407
|
-
const guidesDir =
|
|
442
|
+
const guidesDir = join3(contextDir, "guides");
|
|
408
443
|
mkdirSync(guidesDir, { recursive: true });
|
|
409
|
-
writeFileSync(
|
|
444
|
+
writeFileSync(join3(contextDir, "config.jsonc"), DEFAULT_CONFIG, "utf-8");
|
|
410
445
|
for (const [filename, content] of Object.entries(TEMPLATE_FILES)) {
|
|
411
|
-
writeFileSync(
|
|
446
|
+
writeFileSync(join3(templatesDir, filename), content, "utf-8");
|
|
412
447
|
}
|
|
413
448
|
for (const [filename, content] of Object.entries(GUIDE_FILES)) {
|
|
414
|
-
writeFileSync(
|
|
449
|
+
writeFileSync(join3(guidesDir, filename), content, "utf-8");
|
|
415
450
|
}
|
|
416
451
|
writeVersion(contextDir, PLUGIN_VERSION);
|
|
417
452
|
return true;
|
|
@@ -421,30 +456,30 @@ function scaffoldIfNeeded(projectDir) {
|
|
|
421
456
|
}
|
|
422
457
|
function getStoredVersion(projectDir) {
|
|
423
458
|
try {
|
|
424
|
-
return readFileSync(
|
|
459
|
+
return readFileSync(join3(projectDir, resolveContextDir(projectDir), ".version"), "utf-8").trim();
|
|
425
460
|
} catch {
|
|
426
461
|
return null;
|
|
427
462
|
}
|
|
428
463
|
}
|
|
429
464
|
function writeVersion(contextDir, version) {
|
|
430
|
-
writeFileSync(
|
|
465
|
+
writeFileSync(join3(contextDir, ".version"), version, "utf-8");
|
|
431
466
|
}
|
|
432
467
|
function autoUpdateTemplates(projectDir) {
|
|
433
|
-
const contextDir =
|
|
434
|
-
if (!
|
|
468
|
+
const contextDir = join3(projectDir, resolveContextDir(projectDir));
|
|
469
|
+
if (!existsSync3(contextDir))
|
|
435
470
|
return [];
|
|
436
471
|
const stored = getStoredVersion(projectDir);
|
|
437
472
|
if (stored === PLUGIN_VERSION)
|
|
438
473
|
return [];
|
|
439
|
-
mkdirSync(
|
|
440
|
-
mkdirSync(
|
|
474
|
+
mkdirSync(join3(contextDir, "templates"), { recursive: true });
|
|
475
|
+
mkdirSync(join3(contextDir, "guides"), { recursive: true });
|
|
441
476
|
const filesToUpdate = {
|
|
442
477
|
...Object.fromEntries(Object.entries(TEMPLATE_FILES).map(([f, c]) => [`templates/${f}`, c])),
|
|
443
478
|
...Object.fromEntries(Object.entries(GUIDE_FILES).map(([f, c]) => [`guides/${f}`, c]))
|
|
444
479
|
};
|
|
445
480
|
const updated = [];
|
|
446
481
|
for (const [path, content] of Object.entries(filesToUpdate)) {
|
|
447
|
-
const filePath =
|
|
482
|
+
const filePath = join3(contextDir, path);
|
|
448
483
|
try {
|
|
449
484
|
const existing = readFileSync(filePath, "utf-8");
|
|
450
485
|
if (existing === content)
|
|
@@ -479,10 +514,11 @@ var LIMITS = {
|
|
|
479
514
|
|
|
480
515
|
// src/index.ts
|
|
481
516
|
var __filename2 = fileURLToPath(import.meta.url);
|
|
482
|
-
var __dirname2 =
|
|
517
|
+
var __dirname2 = dirname2(__filename2);
|
|
483
518
|
var plugin = async ({ directory, client }) => {
|
|
484
|
-
const
|
|
485
|
-
const
|
|
519
|
+
const { contextParent: projectRoot } = resolveProjectPaths(directory);
|
|
520
|
+
const scaffolded = scaffoldIfNeeded(projectRoot);
|
|
521
|
+
const contextDir = resolveContextDir(projectRoot);
|
|
486
522
|
if (scaffolded) {
|
|
487
523
|
await client.app.log({
|
|
488
524
|
body: {
|
|
@@ -492,7 +528,7 @@ var plugin = async ({ directory, client }) => {
|
|
|
492
528
|
}
|
|
493
529
|
});
|
|
494
530
|
} else {
|
|
495
|
-
const autoUpdated = autoUpdateTemplates(
|
|
531
|
+
const autoUpdated = autoUpdateTemplates(projectRoot);
|
|
496
532
|
if (autoUpdated.length > 0) {
|
|
497
533
|
await client.app.log({
|
|
498
534
|
body: {
|
|
@@ -508,7 +544,7 @@ var plugin = async ({ directory, client }) => {
|
|
|
508
544
|
config.mcp = config.mcp || {};
|
|
509
545
|
config.mcp["context-mcp"] = {
|
|
510
546
|
type: "local",
|
|
511
|
-
command: ["bun",
|
|
547
|
+
command: ["bun", join4(__dirname2, "mcp.js")]
|
|
512
548
|
};
|
|
513
549
|
},
|
|
514
550
|
"experimental.chat.messages.transform": async (_input, output) => {
|
|
@@ -523,8 +559,8 @@ var plugin = async ({ directory, client }) => {
|
|
|
523
559
|
if (isTurnEndMessage) {
|
|
524
560
|
return;
|
|
525
561
|
}
|
|
526
|
-
const signalPath =
|
|
527
|
-
if (
|
|
562
|
+
const signalPath = join4(projectRoot, DEFAULTS.workCompleteFile);
|
|
563
|
+
if (existsSync4(signalPath)) {
|
|
528
564
|
const content = readFileSync2(signalPath, "utf-8");
|
|
529
565
|
const match = content.match(/^session_id=(.*)$/m);
|
|
530
566
|
const fileSessionId = match ? match[1].trim() : undefined;
|
|
@@ -20,7 +20,7 @@ function resolveContextDir(projectDir) {
|
|
|
20
20
|
// package.json
|
|
21
21
|
var package_default = {
|
|
22
22
|
name: "@ksm0709/context",
|
|
23
|
-
version: "0.
|
|
23
|
+
version: "0.2.0",
|
|
24
24
|
author: {
|
|
25
25
|
name: "TaehoKang",
|
|
26
26
|
email: "ksm07091@gmail.com"
|
|
@@ -418,9 +418,44 @@ function writeVersion(contextDir, version) {
|
|
|
418
418
|
writeFileSync(join2(contextDir, ".version"), version, "utf-8");
|
|
419
419
|
}
|
|
420
420
|
|
|
421
|
+
// src/lib/project-root.ts
|
|
422
|
+
import { existsSync as existsSync3 } from "fs";
|
|
423
|
+
import { join as join3, dirname, resolve } from "path";
|
|
424
|
+
import { homedir } from "os";
|
|
425
|
+
function findGitRoot(startDir) {
|
|
426
|
+
let current = resolve(startDir);
|
|
427
|
+
while (true) {
|
|
428
|
+
if (existsSync3(join3(current, ".git"))) {
|
|
429
|
+
return current;
|
|
430
|
+
}
|
|
431
|
+
const parent = dirname(current);
|
|
432
|
+
if (parent === current) {
|
|
433
|
+
return null;
|
|
434
|
+
}
|
|
435
|
+
current = parent;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
function resolveProjectPaths(startDir) {
|
|
439
|
+
const gitRoot = findGitRoot(startDir);
|
|
440
|
+
if (gitRoot) {
|
|
441
|
+
return {
|
|
442
|
+
contextParent: gitRoot,
|
|
443
|
+
agentsMdPath: join3(gitRoot, "AGENTS.md"),
|
|
444
|
+
claudeMdPath: join3(gitRoot, "CLAUDE.md")
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
const home = homedir();
|
|
448
|
+
const contextDir = join3(home, ".context");
|
|
449
|
+
return {
|
|
450
|
+
contextParent: home,
|
|
451
|
+
agentsMdPath: join3(contextDir, "AGENTS.md"),
|
|
452
|
+
claudeMdPath: join3(contextDir, "CLAUDE.md")
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
|
|
421
456
|
// src/shared/agents-md.ts
|
|
422
|
-
import { existsSync as
|
|
423
|
-
import { dirname } from "path";
|
|
457
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync2, renameSync, writeFileSync as writeFileSync2 } from "fs";
|
|
458
|
+
import { dirname as dirname2 } from "path";
|
|
424
459
|
var START_MARKER = "<!-- context:start -->";
|
|
425
460
|
var END_MARKER = "<!-- context:end -->";
|
|
426
461
|
function renderMarkerBlock(content, trailingNewline) {
|
|
@@ -461,8 +496,8 @@ function writeFileAtomically(filePath, content) {
|
|
|
461
496
|
renameSync(tempPath, filePath);
|
|
462
497
|
}
|
|
463
498
|
function injectIntoAgentsMd(agentsMdPath, content) {
|
|
464
|
-
mkdirSync2(
|
|
465
|
-
if (!
|
|
499
|
+
mkdirSync2(dirname2(agentsMdPath), { recursive: true });
|
|
500
|
+
if (!existsSync4(agentsMdPath)) {
|
|
466
501
|
writeFileAtomically(agentsMdPath, renderMarkerBlock(content, true));
|
|
467
502
|
return;
|
|
468
503
|
}
|
|
@@ -512,7 +547,8 @@ var STATIC_KNOWLEDGE_CONTEXT = `## Knowledge Context
|
|
|
512
547
|
- \uD544\uC694\uD55C \uC778\uC790: daily_note_update_proof, knowledge_note_proof, quality_check_output, checkpoint_commit_hashes, scope_review_notes`;
|
|
513
548
|
|
|
514
549
|
// src/omc/session-start-hook.ts
|
|
515
|
-
import { join as join3 } from "path";
|
|
516
550
|
var projectDir = process.env.CLAUDE_PROJECT_DIR ?? process.cwd();
|
|
517
|
-
|
|
518
|
-
|
|
551
|
+
var paths = resolveProjectPaths(projectDir);
|
|
552
|
+
scaffoldIfNeeded(paths.contextParent);
|
|
553
|
+
injectIntoAgentsMd(paths.agentsMdPath, STATIC_KNOWLEDGE_CONTEXT);
|
|
554
|
+
injectIntoAgentsMd(paths.claudeMdPath, STATIC_KNOWLEDGE_CONTEXT);
|
package/dist/omx/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/omx/index.ts
|
|
2
|
-
import { existsSync as
|
|
3
|
-
import { join as
|
|
2
|
+
import { existsSync as existsSync8, readFileSync as readFileSync6, unlinkSync } from "node:fs";
|
|
3
|
+
import { join as join8 } from "node:path";
|
|
4
4
|
|
|
5
5
|
// src/constants.ts
|
|
6
6
|
var DEFAULTS = {
|
|
@@ -99,13 +99,48 @@ function loadConfig(projectDir) {
|
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
// src/lib/project-root.ts
|
|
103
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
104
|
+
import { join as join3, dirname, resolve } from "node:path";
|
|
105
|
+
import { homedir } from "node:os";
|
|
106
|
+
function findGitRoot(startDir) {
|
|
107
|
+
let current = resolve(startDir);
|
|
108
|
+
while (true) {
|
|
109
|
+
if (existsSync2(join3(current, ".git"))) {
|
|
110
|
+
return current;
|
|
111
|
+
}
|
|
112
|
+
const parent = dirname(current);
|
|
113
|
+
if (parent === current) {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
current = parent;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function resolveProjectPaths(startDir) {
|
|
120
|
+
const gitRoot = findGitRoot(startDir);
|
|
121
|
+
if (gitRoot) {
|
|
122
|
+
return {
|
|
123
|
+
contextParent: gitRoot,
|
|
124
|
+
agentsMdPath: join3(gitRoot, "AGENTS.md"),
|
|
125
|
+
claudeMdPath: join3(gitRoot, "CLAUDE.md")
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
const home = homedir();
|
|
129
|
+
const contextDir = join3(home, ".context");
|
|
130
|
+
return {
|
|
131
|
+
contextParent: home,
|
|
132
|
+
agentsMdPath: join3(contextDir, "AGENTS.md"),
|
|
133
|
+
claudeMdPath: join3(contextDir, "CLAUDE.md")
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
102
137
|
// src/lib/scaffold.ts
|
|
103
|
-
import { existsSync as
|
|
104
|
-
import { join as
|
|
138
|
+
import { existsSync as existsSync3, mkdirSync, readFileSync as readFileSync2, writeFileSync } from "node:fs";
|
|
139
|
+
import { join as join4 } from "node:path";
|
|
105
140
|
// package.json
|
|
106
141
|
var package_default = {
|
|
107
142
|
name: "@ksm0709/context",
|
|
108
|
-
version: "0.
|
|
143
|
+
version: "0.2.0",
|
|
109
144
|
author: {
|
|
110
145
|
name: "TaehoKang",
|
|
111
146
|
email: "ksm07091@gmail.com"
|
|
@@ -477,21 +512,21 @@ var TEMPLATE_FILES = {
|
|
|
477
512
|
"work-complete.txt": DEFAULT_WORK_COMPLETE_TEMPLATE
|
|
478
513
|
};
|
|
479
514
|
function scaffoldIfNeeded(projectDir) {
|
|
480
|
-
const contextDir =
|
|
481
|
-
if (
|
|
515
|
+
const contextDir = join4(projectDir, resolveContextDir(projectDir));
|
|
516
|
+
if (existsSync3(contextDir)) {
|
|
482
517
|
return false;
|
|
483
518
|
}
|
|
484
519
|
try {
|
|
485
|
-
const templatesDir =
|
|
520
|
+
const templatesDir = join4(contextDir, "templates");
|
|
486
521
|
mkdirSync(templatesDir, { recursive: true });
|
|
487
|
-
const guidesDir =
|
|
522
|
+
const guidesDir = join4(contextDir, "guides");
|
|
488
523
|
mkdirSync(guidesDir, { recursive: true });
|
|
489
|
-
writeFileSync(
|
|
524
|
+
writeFileSync(join4(contextDir, "config.jsonc"), DEFAULT_CONFIG, "utf-8");
|
|
490
525
|
for (const [filename, content] of Object.entries(TEMPLATE_FILES)) {
|
|
491
|
-
writeFileSync(
|
|
526
|
+
writeFileSync(join4(templatesDir, filename), content, "utf-8");
|
|
492
527
|
}
|
|
493
528
|
for (const [filename, content] of Object.entries(GUIDE_FILES)) {
|
|
494
|
-
writeFileSync(
|
|
529
|
+
writeFileSync(join4(guidesDir, filename), content, "utf-8");
|
|
495
530
|
}
|
|
496
531
|
writeVersion(contextDir, PLUGIN_VERSION);
|
|
497
532
|
return true;
|
|
@@ -500,12 +535,12 @@ function scaffoldIfNeeded(projectDir) {
|
|
|
500
535
|
}
|
|
501
536
|
}
|
|
502
537
|
function writeVersion(contextDir, version) {
|
|
503
|
-
writeFileSync(
|
|
538
|
+
writeFileSync(join4(contextDir, ".version"), version, "utf-8");
|
|
504
539
|
}
|
|
505
540
|
|
|
506
541
|
// src/shared/agents-md.ts
|
|
507
|
-
import { existsSync as
|
|
508
|
-
import { dirname } from "node:path";
|
|
542
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync3, renameSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
543
|
+
import { dirname as dirname2 } from "node:path";
|
|
509
544
|
var START_MARKER = "<!-- context:start -->";
|
|
510
545
|
var END_MARKER = "<!-- context:end -->";
|
|
511
546
|
function renderMarkerBlock(content, trailingNewline) {
|
|
@@ -546,8 +581,8 @@ function writeFileAtomically(filePath, content) {
|
|
|
546
581
|
renameSync(tempPath, filePath);
|
|
547
582
|
}
|
|
548
583
|
function injectIntoAgentsMd(agentsMdPath, content) {
|
|
549
|
-
mkdirSync2(
|
|
550
|
-
if (!
|
|
584
|
+
mkdirSync2(dirname2(agentsMdPath), { recursive: true });
|
|
585
|
+
if (!existsSync4(agentsMdPath)) {
|
|
551
586
|
writeFileAtomically(agentsMdPath, renderMarkerBlock(content, true));
|
|
552
587
|
return;
|
|
553
588
|
}
|
|
@@ -557,11 +592,11 @@ function injectIntoAgentsMd(agentsMdPath, content) {
|
|
|
557
592
|
}
|
|
558
593
|
|
|
559
594
|
// src/shared/codex-settings.ts
|
|
560
|
-
import { existsSync as
|
|
561
|
-
import { homedir } from "node:os";
|
|
562
|
-
import { isAbsolute, join as
|
|
595
|
+
import { existsSync as existsSync5, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
|
|
596
|
+
import { homedir as homedir2 } from "node:os";
|
|
597
|
+
import { isAbsolute, join as join5 } from "node:path";
|
|
563
598
|
var STALE_MOCK_MCP_SERVER_NAME = "mock-mcp";
|
|
564
|
-
var codexConfigPath =
|
|
599
|
+
var codexConfigPath = join5(homedir2(), ".codex", "config.toml");
|
|
565
600
|
function findMcpServerBlockRange(lines, serverName) {
|
|
566
601
|
const header = `[mcp_servers.${serverName}]`;
|
|
567
602
|
const start = lines.findIndex((line) => line.trim() === header);
|
|
@@ -588,7 +623,7 @@ function resolveFirstArgPath(blockLines) {
|
|
|
588
623
|
return null;
|
|
589
624
|
}
|
|
590
625
|
function pruneStaleMockMcpServer() {
|
|
591
|
-
if (!
|
|
626
|
+
if (!existsSync5(codexConfigPath)) {
|
|
592
627
|
return false;
|
|
593
628
|
}
|
|
594
629
|
const content = readFileSync4(codexConfigPath, "utf8");
|
|
@@ -600,7 +635,7 @@ function pruneStaleMockMcpServer() {
|
|
|
600
635
|
}
|
|
601
636
|
const blockLines = lines.slice(blockRange.start, blockRange.end);
|
|
602
637
|
const firstArgPath = resolveFirstArgPath(blockLines);
|
|
603
|
-
if (!firstArgPath || !isAbsolute(firstArgPath) ||
|
|
638
|
+
if (!firstArgPath || !isAbsolute(firstArgPath) || existsSync5(firstArgPath)) {
|
|
604
639
|
return false;
|
|
605
640
|
}
|
|
606
641
|
const nextLines = [...lines.slice(0, blockRange.start), ...lines.slice(blockRange.end)];
|
|
@@ -650,32 +685,32 @@ var STATIC_KNOWLEDGE_CONTEXT = `## Knowledge Context
|
|
|
650
685
|
- 필요한 인자: daily_note_update_proof, knowledge_note_proof, quality_check_output, checkpoint_commit_hashes, scope_review_notes`;
|
|
651
686
|
|
|
652
687
|
// src/omx/registry.ts
|
|
653
|
-
import { join as
|
|
654
|
-
import { existsSync as
|
|
688
|
+
import { join as join7, dirname as dirname4 } from "node:path";
|
|
689
|
+
import { existsSync as existsSync7, readFileSync as readFileSync5, writeFileSync as writeFileSync4, mkdirSync as mkdirSync3 } from "node:fs";
|
|
655
690
|
import { execSync } from "node:child_process";
|
|
656
|
-
import { homedir as
|
|
691
|
+
import { homedir as homedir3 } from "node:os";
|
|
657
692
|
|
|
658
693
|
// src/shared/mcp-path.ts
|
|
659
694
|
import { fileURLToPath } from "node:url";
|
|
660
|
-
import { dirname as
|
|
661
|
-
import { existsSync as
|
|
695
|
+
import { dirname as dirname3, join as join6, resolve as resolve2 } from "node:path";
|
|
696
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
662
697
|
import { createRequire } from "node:module";
|
|
663
698
|
function resolveMcpPath() {
|
|
664
699
|
try {
|
|
665
700
|
const req = createRequire(import.meta.url);
|
|
666
701
|
const pkgJsonPath = req.resolve("@ksm0709/context/package.json");
|
|
667
|
-
const pkgRoot =
|
|
668
|
-
const distMcp =
|
|
669
|
-
if (
|
|
702
|
+
const pkgRoot = dirname3(pkgJsonPath);
|
|
703
|
+
const distMcp = join6(pkgRoot, "dist", "mcp.js");
|
|
704
|
+
if (existsSync6(distMcp))
|
|
670
705
|
return distMcp;
|
|
671
706
|
} catch {}
|
|
672
707
|
const currentFile = fileURLToPath(import.meta.url);
|
|
673
|
-
const currentDir =
|
|
674
|
-
const distMcpPath =
|
|
675
|
-
if (
|
|
708
|
+
const currentDir = dirname3(currentFile);
|
|
709
|
+
const distMcpPath = resolve2(currentDir, "..", "mcp.js");
|
|
710
|
+
if (existsSync6(distMcpPath))
|
|
676
711
|
return distMcpPath;
|
|
677
|
-
const srcMcpPath =
|
|
678
|
-
if (
|
|
712
|
+
const srcMcpPath = resolve2(currentDir, "..", "mcp.ts");
|
|
713
|
+
if (existsSync6(srcMcpPath))
|
|
679
714
|
return srcMcpPath;
|
|
680
715
|
return distMcpPath;
|
|
681
716
|
}
|
|
@@ -690,21 +725,21 @@ function resolveBunPath() {
|
|
|
690
725
|
}
|
|
691
726
|
function getRegistryPaths() {
|
|
692
727
|
return [
|
|
693
|
-
|
|
694
|
-
|
|
728
|
+
join7(homedir3(), ".omx", "mcp-registry.json"),
|
|
729
|
+
join7(homedir3(), ".omc", "mcp-registry.json")
|
|
695
730
|
];
|
|
696
731
|
}
|
|
697
732
|
function ensureMcpRegistered(sdkLog) {
|
|
698
733
|
const registryPaths = getRegistryPaths();
|
|
699
734
|
let targetPath = registryPaths[0];
|
|
700
735
|
for (const p of registryPaths) {
|
|
701
|
-
if (
|
|
736
|
+
if (existsSync7(p)) {
|
|
702
737
|
targetPath = p;
|
|
703
738
|
break;
|
|
704
739
|
}
|
|
705
740
|
}
|
|
706
741
|
let registry = {};
|
|
707
|
-
if (
|
|
742
|
+
if (existsSync7(targetPath)) {
|
|
708
743
|
try {
|
|
709
744
|
const content = readFileSync5(targetPath, "utf-8");
|
|
710
745
|
registry = JSON.parse(content);
|
|
@@ -734,7 +769,7 @@ function ensureMcpRegistered(sdkLog) {
|
|
|
734
769
|
}
|
|
735
770
|
if (changed) {
|
|
736
771
|
try {
|
|
737
|
-
mkdirSync3(
|
|
772
|
+
mkdirSync3(dirname4(targetPath), { recursive: true });
|
|
738
773
|
writeFileSync4(targetPath, JSON.stringify(registry, null, 2), "utf-8");
|
|
739
774
|
if (sdkLog) {
|
|
740
775
|
sdkLog(`[INFO] Registered context-mcp in ${targetPath}`);
|
|
@@ -766,7 +801,7 @@ function runTmux(args) {
|
|
|
766
801
|
return { ok: true };
|
|
767
802
|
}
|
|
768
803
|
function sleep(ms) {
|
|
769
|
-
return new Promise((
|
|
804
|
+
return new Promise((resolve3) => globalThis.setTimeout(resolve3, ms));
|
|
770
805
|
}
|
|
771
806
|
async function sendTmuxSubmitSequence(target, attempts = 3) {
|
|
772
807
|
const totalAttempts = Math.max(1, Math.floor(attempts));
|
|
@@ -834,11 +869,13 @@ async function logWarn(sdk, message, meta = {}) {
|
|
|
834
869
|
}
|
|
835
870
|
async function onSessionStart(event, sdk) {
|
|
836
871
|
const projectDir = resolveProjectDir(event);
|
|
872
|
+
const paths = resolveProjectPaths(projectDir);
|
|
837
873
|
if (pruneStaleMockMcpServer()) {
|
|
838
874
|
await sdk.log.info("Removed stale mock-mcp from ~/.codex/config.toml because its target file is missing.");
|
|
839
875
|
}
|
|
840
|
-
scaffoldIfNeeded(
|
|
841
|
-
injectIntoAgentsMd(
|
|
876
|
+
scaffoldIfNeeded(paths.contextParent);
|
|
877
|
+
injectIntoAgentsMd(paths.agentsMdPath, STATIC_KNOWLEDGE_CONTEXT);
|
|
878
|
+
injectIntoAgentsMd(paths.claudeMdPath, STATIC_KNOWLEDGE_CONTEXT);
|
|
842
879
|
await sdk.log.info(`Injected context into AGENTS.md for ${projectDir}`);
|
|
843
880
|
const wasRegistered = ensureMcpRegistered(sdk.log.info);
|
|
844
881
|
if (wasRegistered) {
|
|
@@ -856,7 +893,8 @@ async function onSessionStart(event, sdk) {
|
|
|
856
893
|
}
|
|
857
894
|
async function onTurnComplete(event, sdk) {
|
|
858
895
|
const projectDir = resolveProjectDir(event);
|
|
859
|
-
const
|
|
896
|
+
const paths = resolveProjectPaths(projectDir);
|
|
897
|
+
const config = loadConfig(paths.contextParent);
|
|
860
898
|
const strategy = config.omx?.turnEnd?.strategy ?? "off";
|
|
861
899
|
if (strategy !== "turn-complete-sendkeys") {
|
|
862
900
|
return;
|
|
@@ -878,8 +916,8 @@ async function onTurnComplete(event, sdk) {
|
|
|
878
916
|
}
|
|
879
917
|
const followupScopeKey = resolveFollowupScopeKey(event);
|
|
880
918
|
let pendingFollowupScopes = typeof sdk.state?.read === "function" ? await sdk.state.read(TURN_END_PENDING_SKIP_KEY, {}) ?? {} : {};
|
|
881
|
-
const workCompleteFile =
|
|
882
|
-
if (
|
|
919
|
+
const workCompleteFile = join8(paths.contextParent, DEFAULTS.workCompleteFile);
|
|
920
|
+
if (existsSync8(workCompleteFile)) {
|
|
883
921
|
const content = readFileSync6(workCompleteFile, "utf-8");
|
|
884
922
|
const { sessionId: fileSessionId, turnId: fileTurnId } = parseWorkComplete(content);
|
|
885
923
|
const currentScopeId = event.session_id ?? event.thread_id ?? "";
|
|
@@ -946,7 +984,7 @@ async function onTurnComplete(event, sdk) {
|
|
|
946
984
|
${turnEnd}
|
|
947
985
|
</system-reminder>`;
|
|
948
986
|
const sessionName = typeof event.context?.session_name === "string" && event.context.session_name.trim().length > 0 ? event.context.session_name.trim() : undefined;
|
|
949
|
-
await new Promise((
|
|
987
|
+
await new Promise((resolve3) => globalThis.setTimeout(resolve3, 500));
|
|
950
988
|
if (typeof sdk.tmux?.sendKeys === "function") {}
|
|
951
989
|
const result = await sdk.tmux.sendKeys({
|
|
952
990
|
sessionName,
|