@contextai-core/cli 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/actions/init.js +9 -40
- package/src/logic/file-ops.js +22 -10
package/package.json
CHANGED
package/src/actions/init.js
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import chalk from "chalk";
|
|
3
3
|
import path from "path";
|
|
4
4
|
import fs from "fs";
|
|
5
|
-
import { installPackage } from "./install.js";
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
|
-
* Initializes the ContextAI Shared Brain (.ai)
|
|
7
|
+
* Initializes the ContextAI Shared Brain (.ai).
|
|
8
|
+
* Creates the directory structure but installs NO packs by default.
|
|
9
9
|
*/
|
|
10
10
|
export async function init() {
|
|
11
11
|
console.log(chalk.green('🧠 Initializing ContextAI Shared Brain...'));
|
|
@@ -14,44 +14,13 @@ export async function init() {
|
|
|
14
14
|
// 1. Create .ai directory if missing
|
|
15
15
|
if (!fs.existsSync(aiDir)) {
|
|
16
16
|
fs.mkdirSync(aiDir);
|
|
17
|
+
console.log(chalk.blue(' Created .ai/ directory.'));
|
|
18
|
+
} else {
|
|
19
|
+
console.log(chalk.yellow(' .ai/ directory already exists.'));
|
|
17
20
|
}
|
|
18
21
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
try {
|
|
26
|
-
// 3. Delegate to Install Action
|
|
27
|
-
// "universal-context-protocol" should be the slug of the Core UCP in our DB.
|
|
28
|
-
// For now, if that pack doesn't exist, we fallback to the "seed" method?
|
|
29
|
-
// NO, we should enforce the "Git/Marketplace" model.
|
|
30
|
-
|
|
31
|
-
console.log(chalk.blue('⬇️ Downloading Universal Context Protocol (Core OS)...'));
|
|
32
|
-
|
|
33
|
-
// We call installPackage directly.
|
|
34
|
-
// We assume "universal-context-protocol" is free and public.
|
|
35
|
-
await installPackage("universal-context-protocol", {});
|
|
36
|
-
|
|
37
|
-
// 4. Create Bootloader (Traffic Cop) if missing
|
|
38
|
-
const bootPath = path.join(aiDir, 'boot.md');
|
|
39
|
-
if (!fs.existsSync(bootPath)) {
|
|
40
|
-
fs.writeFileSync(
|
|
41
|
-
bootPath,
|
|
42
|
-
`# AI Context Container\n\nThis project uses multiple context protocols.\n\n## Active Protocols\n1. **UCP** (Core OS): [Unified Context Protocol](./ucp/README.md)\n - Use for: General Project Context, Workflows.\n`
|
|
43
|
-
);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
console.log(chalk.green('\n✅ Initialization Complete!'));
|
|
47
|
-
console.log(chalk.gray(' Your agent now has a brain in .ai/'));
|
|
48
|
-
|
|
49
|
-
} catch (error) {
|
|
50
|
-
console.error(chalk.red(`\n❌ Init Failed: ${error.message}`));
|
|
51
|
-
console.error(chalk.yellow(' Ensure you have internet connection and the "universal-context-protocol" pack is live.'));
|
|
52
|
-
// Fallback or exit?
|
|
53
|
-
// For resilience, maybe write a minimal skeleton if download fails?
|
|
54
|
-
// User asked to "download from live ucp template link".
|
|
55
|
-
process.exit(1);
|
|
56
|
-
}
|
|
22
|
+
console.log(chalk.green('\n✅ Initialization Complete!'));
|
|
23
|
+
console.log(chalk.white(' Your project is ready context.'));
|
|
24
|
+
console.log(chalk.cyan('\n Next Step: Install a Context Pack'));
|
|
25
|
+
console.log(chalk.gray(' $ npx contextai install @<username>/ucp'));
|
|
57
26
|
}
|
package/src/logic/file-ops.js
CHANGED
|
@@ -8,6 +8,14 @@ import chalk from 'chalk';
|
|
|
8
8
|
*/
|
|
9
9
|
export async function smartWriteFile(filePath, content, reason) {
|
|
10
10
|
const fullPath = path.resolve(process.cwd(), filePath);
|
|
11
|
+
|
|
12
|
+
// SAFETY: Restrict usage to .ai directory (and context folders)
|
|
13
|
+
// This prevents the tool from conflicting with the Agent's native coding capabilities.
|
|
14
|
+
const relPath = path.relative(process.cwd(), fullPath);
|
|
15
|
+
if (!relPath.startsWith('.ai') && !relPath.startsWith('.context')) {
|
|
16
|
+
throw new Error(`ACCESS DENIED: 'contextai write' is restricted to the .ai/ directory.\nUse your native 'write_file' tool for application code.`);
|
|
17
|
+
}
|
|
18
|
+
|
|
11
19
|
const dir = path.dirname(fullPath);
|
|
12
20
|
|
|
13
21
|
// 1. Write the file
|
|
@@ -16,19 +24,23 @@ export async function smartWriteFile(filePath, content, reason) {
|
|
|
16
24
|
}
|
|
17
25
|
fs.writeFileSync(fullPath, content, 'utf8');
|
|
18
26
|
|
|
19
|
-
// 2.
|
|
20
|
-
|
|
21
|
-
|
|
27
|
+
// 2. System Audit Log (Immutable)
|
|
28
|
+
// Tracks "What happened" for safety/replay.
|
|
29
|
+
// Agent cannot modify this directly; it's a side-effect of the tool.
|
|
30
|
+
const aiDir = path.join(process.cwd(), '.ai');
|
|
31
|
+
const auditPath = path.join(aiDir, 'audit.log');
|
|
22
32
|
|
|
23
|
-
if (fs.existsSync(
|
|
24
|
-
|
|
25
|
-
|
|
33
|
+
if (!fs.existsSync(aiDir)) {
|
|
34
|
+
try { fs.mkdirSync(aiDir); } catch (e) { }
|
|
35
|
+
}
|
|
26
36
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
changelog += `\n${entry}`;
|
|
37
|
+
const timestamp = new Date().toISOString();
|
|
38
|
+
const logEntry = `[${timestamp}] ACTION:WRITE file="${filePath}" reason="${reason}"\n`;
|
|
30
39
|
|
|
31
|
-
|
|
40
|
+
try {
|
|
41
|
+
fs.appendFileSync(auditPath, logEntry, 'utf8');
|
|
42
|
+
} catch (e) {
|
|
43
|
+
// Silently fail logging rather than breaking the build
|
|
32
44
|
}
|
|
33
45
|
|
|
34
46
|
return { success: true, path: fullPath };
|