@josfox/jos 4.0.7 → 4.1.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/LICENSE +21 -21
- package/README.md +138 -186
- package/bin/jos +160 -98
- package/bin/jos.cmd +5 -0
- package/package.json +40 -35
- package/src/adapters/index.js +16 -0
- package/src/adapters/native.js +41 -0
- package/src/adapters/ollama.js +140 -0
- package/src/commands/add.js +145 -145
- package/src/commands/get.js +245 -245
- package/src/commands/init.js +162 -162
- package/src/commands/llm.js +159 -0
- package/src/commands/prompts.js +229 -0
- package/src/commands/repo.js +139 -139
- package/src/commands/run.js +244 -244
- package/src/commands/secrets.js +137 -137
- package/src/commands/validate.js +194 -190
- package/src/commands/verify.js +98 -0
- package/src/serve.js +781 -780
- package/src/utils/crypto.js +41 -0
- package/src/utils/request.js +41 -0
- package/src/index.js +0 -0
package/src/commands/init.js
CHANGED
|
@@ -1,162 +1,162 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* JOS INIT Command - Create new .jos artifacts
|
|
3
|
-
* Creates a minimal valid .jos with detached integrity manifest
|
|
4
|
-
* Format version v0.0.7 — Specification maturity v0.1.0 (Alpha)
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const fs = require('fs');
|
|
8
|
-
const path = require('path');
|
|
9
|
-
const crypto = require('crypto');
|
|
10
|
-
|
|
11
|
-
const C = {
|
|
12
|
-
reset: '\x1b[0m', bold: '\x1b[1m',
|
|
13
|
-
purple: '\x1b[38;5;135m', cyan: '\x1b[38;5;51m',
|
|
14
|
-
green: '\x1b[38;5;78m', gray: '\x1b[38;5;245m'
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
exports.execute = async (args, home) => {
|
|
18
|
-
const name = args[0] || 'new-artifact';
|
|
19
|
-
const type = args.includes('--pipeline') ? 'pipeline' : 'atom';
|
|
20
|
-
const filename = `${name}.jos`;
|
|
21
|
-
|
|
22
|
-
if (args.includes('--help') || args.includes('-h')) {
|
|
23
|
-
console.log(`
|
|
24
|
-
${C.purple}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${C.reset}
|
|
25
|
-
${C.bold}JOS INIT${C.reset} // Create new .jos artifacts
|
|
26
|
-
${C.purple}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${C.reset}
|
|
27
|
-
|
|
28
|
-
${C.bold}Usage:${C.reset}
|
|
29
|
-
jos init <name> [options]
|
|
30
|
-
|
|
31
|
-
${C.bold}Options:${C.reset}
|
|
32
|
-
--pipeline Create a pipeline artifact (default: atom)
|
|
33
|
-
|
|
34
|
-
${C.bold}Creates:${C.reset}
|
|
35
|
-
<name>.jos The artifact file
|
|
36
|
-
<name>.jos.sig.json Detached integrity manifest
|
|
37
|
-
`);
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
console.log(`\n${C.purple}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${C.reset}`);
|
|
42
|
-
console.log(`${C.bold}JOS INIT${C.reset} // ${C.gray}Creating ${type} artifact${C.reset}`);
|
|
43
|
-
console.log(`${C.purple}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${C.reset}\n`);
|
|
44
|
-
|
|
45
|
-
// Create artifact with full JOSFOXAI + MAGIC compliance
|
|
46
|
-
const template = {
|
|
47
|
-
"$schema": "https://josfox.ai/schemas/jos-0.0.7.json",
|
|
48
|
-
"$comment": "Format version v0.0.7 — Specification maturity v0.1.0 (Alpha)",
|
|
49
|
-
|
|
50
|
-
// JOSFOXAI Kernel
|
|
51
|
-
"jos": {
|
|
52
|
-
"open": `jos run ${type}`,
|
|
53
|
-
"supports": ["@josfox/jos", "josctl"],
|
|
54
|
-
"canonical": "Format version v0.0.7 — Specification maturity v0.1.0 (Alpha)"
|
|
55
|
-
},
|
|
56
|
-
"orchestration_contract": {
|
|
57
|
-
"version": "0.0.7",
|
|
58
|
-
"mode": "sync"
|
|
59
|
-
},
|
|
60
|
-
"id_jos": `${type}-${name}-${Date.now()}`,
|
|
61
|
-
"adaptive_ai": {
|
|
62
|
-
"learning_mode": "frozen",
|
|
63
|
-
"llm_friendly_sentence": `This ${type} artifact performs the ${name} task.`
|
|
64
|
-
},
|
|
65
|
-
"security": {
|
|
66
|
-
"type": "open",
|
|
67
|
-
"permissions": [],
|
|
68
|
-
"health_check": null,
|
|
69
|
-
"integrity": null,
|
|
70
|
-
"integrity_ref": `./${filename}.sig.json`
|
|
71
|
-
},
|
|
72
|
-
"files": [],
|
|
73
|
-
"orchestration": {
|
|
74
|
-
"state": { "current_status": "idle" },
|
|
75
|
-
"definitions": {
|
|
76
|
-
"main_task": {
|
|
77
|
-
"type": "shell",
|
|
78
|
-
"description": "Main task - replace with your command",
|
|
79
|
-
"command": "echo 'Hello from " + name + "'"
|
|
80
|
-
}
|
|
81
|
-
},
|
|
82
|
-
"flows": {
|
|
83
|
-
"main": {
|
|
84
|
-
"description": "Main execution flow",
|
|
85
|
-
"steps": ["main_task"]
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
},
|
|
89
|
-
"x_run_params": {
|
|
90
|
-
"timeout": 300,
|
|
91
|
-
"retry_on_failure": false
|
|
92
|
-
},
|
|
93
|
-
|
|
94
|
-
// MAGIC Kernel
|
|
95
|
-
"meta": {
|
|
96
|
-
"version": "1.0.0",
|
|
97
|
-
"type": type,
|
|
98
|
-
"name": name,
|
|
99
|
-
"provider": "local",
|
|
100
|
-
"author": "JOS Developer",
|
|
101
|
-
"canonical_version": "Format version v0.0.7 — Specification maturity v0.1.0 (Alpha)"
|
|
102
|
-
},
|
|
103
|
-
"artifacts": {
|
|
104
|
-
"description": `Auto-generated ${type} artifact. Update this description.`,
|
|
105
|
-
"outputs": []
|
|
106
|
-
},
|
|
107
|
-
"guardrails": {
|
|
108
|
-
"avoid": [],
|
|
109
|
-
"max_retries": 1
|
|
110
|
-
},
|
|
111
|
-
"intention": {
|
|
112
|
-
"objective": "Define your objective here",
|
|
113
|
-
"success_criteria": "Define success criteria here"
|
|
114
|
-
},
|
|
115
|
-
"capabilities": []
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
// Write artifact
|
|
119
|
-
const content = JSON.stringify(template, null, 2);
|
|
120
|
-
fs.writeFileSync(filename, content);
|
|
121
|
-
console.log(`${C.green}✓ Created:${C.reset} ${filename}`);
|
|
122
|
-
|
|
123
|
-
// Generate integrity manifest
|
|
124
|
-
const sha256 = crypto.createHash('sha256').update(content).digest('hex');
|
|
125
|
-
const stats = fs.statSync(filename);
|
|
126
|
-
|
|
127
|
-
const manifest = {
|
|
128
|
-
"$schema": "https://josfox.ai/schemas/jos-manifest-0.0.7.json",
|
|
129
|
-
"manifest_version": "1.0.0",
|
|
130
|
-
"artifact_ref": filename,
|
|
131
|
-
"artifact_sha256": sha256,
|
|
132
|
-
"artifact_size_bytes": stats.size,
|
|
133
|
-
"timestamp": new Date().toISOString(),
|
|
134
|
-
"generated_by": "jos init command",
|
|
135
|
-
"canonical_version": "Format version v0.0.7 — Specification maturity v0.1.0 (Alpha)"
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
const manifestPath = filename + '.sig.json';
|
|
139
|
-
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
|
|
140
|
-
console.log(`${C.green}✓ Created:${C.reset} ${manifestPath}`);
|
|
141
|
-
console.log(`${C.gray} SHA256: ${sha256}${C.reset}`);
|
|
142
|
-
|
|
143
|
-
console.log(`
|
|
144
|
-
${C.cyan}Next steps:${C.reset}
|
|
145
|
-
1. Edit ${filename} to define your tasks
|
|
146
|
-
2. Run: ${C.purple}jos validate ${filename}${C.reset}
|
|
147
|
-
3. Run: ${C.purple}jos run ${filename}${C.reset}
|
|
148
|
-
`);
|
|
149
|
-
|
|
150
|
-
// Log to witness
|
|
151
|
-
const runDir = path.join(home, 'runs', 'init-' + new Date().toISOString().replace(/[:.]/g, '-'));
|
|
152
|
-
if (!fs.existsSync(runDir)) fs.mkdirSync(runDir, { recursive: true });
|
|
153
|
-
|
|
154
|
-
const event = {
|
|
155
|
-
timestamp: new Date().toISOString(),
|
|
156
|
-
type: 'init:created',
|
|
157
|
-
artifact: filename,
|
|
158
|
-
manifest: manifestPath,
|
|
159
|
-
sha256: sha256
|
|
160
|
-
};
|
|
161
|
-
fs.appendFileSync(path.join(runDir, 'events.jsonl'), JSON.stringify(event) + '\n');
|
|
162
|
-
};
|
|
1
|
+
/**
|
|
2
|
+
* JOS INIT Command - Create new .jos artifacts
|
|
3
|
+
* Creates a minimal valid .jos with detached integrity manifest
|
|
4
|
+
* Format version v0.0.7 — Specification maturity v0.1.0 (Alpha)
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const crypto = require('crypto');
|
|
10
|
+
|
|
11
|
+
const C = {
|
|
12
|
+
reset: '\x1b[0m', bold: '\x1b[1m',
|
|
13
|
+
purple: '\x1b[38;5;135m', cyan: '\x1b[38;5;51m',
|
|
14
|
+
green: '\x1b[38;5;78m', gray: '\x1b[38;5;245m'
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
exports.execute = async (args, home) => {
|
|
18
|
+
const name = args[0] || 'new-artifact';
|
|
19
|
+
const type = args.includes('--pipeline') ? 'pipeline' : 'atom';
|
|
20
|
+
const filename = `${name}.jos`;
|
|
21
|
+
|
|
22
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
23
|
+
console.log(`
|
|
24
|
+
${C.purple}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${C.reset}
|
|
25
|
+
${C.bold}JOS INIT${C.reset} // Create new .jos artifacts
|
|
26
|
+
${C.purple}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${C.reset}
|
|
27
|
+
|
|
28
|
+
${C.bold}Usage:${C.reset}
|
|
29
|
+
jos init <name> [options]
|
|
30
|
+
|
|
31
|
+
${C.bold}Options:${C.reset}
|
|
32
|
+
--pipeline Create a pipeline artifact (default: atom)
|
|
33
|
+
|
|
34
|
+
${C.bold}Creates:${C.reset}
|
|
35
|
+
<name>.jos The artifact file
|
|
36
|
+
<name>.jos.sig.json Detached integrity manifest
|
|
37
|
+
`);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
console.log(`\n${C.purple}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${C.reset}`);
|
|
42
|
+
console.log(`${C.bold}JOS INIT${C.reset} // ${C.gray}Creating ${type} artifact${C.reset}`);
|
|
43
|
+
console.log(`${C.purple}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${C.reset}\n`);
|
|
44
|
+
|
|
45
|
+
// Create artifact with full JOSFOXAI + MAGIC compliance
|
|
46
|
+
const template = {
|
|
47
|
+
"$schema": "https://josfox.ai/schemas/jos-0.0.7.json",
|
|
48
|
+
"$comment": "Format version v0.0.7 — Specification maturity v0.1.0 (Alpha)",
|
|
49
|
+
|
|
50
|
+
// JOSFOXAI Kernel
|
|
51
|
+
"jos": {
|
|
52
|
+
"open": `jos run ${type}`,
|
|
53
|
+
"supports": ["@josfox/jos", "josctl"],
|
|
54
|
+
"canonical": "Format version v0.0.7 — Specification maturity v0.1.0 (Alpha)"
|
|
55
|
+
},
|
|
56
|
+
"orchestration_contract": {
|
|
57
|
+
"version": "0.0.7",
|
|
58
|
+
"mode": "sync"
|
|
59
|
+
},
|
|
60
|
+
"id_jos": `${type}-${name}-${Date.now()}`,
|
|
61
|
+
"adaptive_ai": {
|
|
62
|
+
"learning_mode": "frozen",
|
|
63
|
+
"llm_friendly_sentence": `This ${type} artifact performs the ${name} task.`
|
|
64
|
+
},
|
|
65
|
+
"security": {
|
|
66
|
+
"type": "open",
|
|
67
|
+
"permissions": [],
|
|
68
|
+
"health_check": null,
|
|
69
|
+
"integrity": null,
|
|
70
|
+
"integrity_ref": `./${filename}.sig.json`
|
|
71
|
+
},
|
|
72
|
+
"files": [],
|
|
73
|
+
"orchestration": {
|
|
74
|
+
"state": { "current_status": "idle" },
|
|
75
|
+
"definitions": {
|
|
76
|
+
"main_task": {
|
|
77
|
+
"type": "shell",
|
|
78
|
+
"description": "Main task - replace with your command",
|
|
79
|
+
"command": "echo 'Hello from " + name + "'"
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
"flows": {
|
|
83
|
+
"main": {
|
|
84
|
+
"description": "Main execution flow",
|
|
85
|
+
"steps": ["main_task"]
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
"x_run_params": {
|
|
90
|
+
"timeout": 300,
|
|
91
|
+
"retry_on_failure": false
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
// MAGIC Kernel
|
|
95
|
+
"meta": {
|
|
96
|
+
"version": "1.0.0",
|
|
97
|
+
"type": type,
|
|
98
|
+
"name": name,
|
|
99
|
+
"provider": "local",
|
|
100
|
+
"author": "JOS Developer",
|
|
101
|
+
"canonical_version": "Format version v0.0.7 — Specification maturity v0.1.0 (Alpha)"
|
|
102
|
+
},
|
|
103
|
+
"artifacts": {
|
|
104
|
+
"description": `Auto-generated ${type} artifact. Update this description.`,
|
|
105
|
+
"outputs": []
|
|
106
|
+
},
|
|
107
|
+
"guardrails": {
|
|
108
|
+
"avoid": [],
|
|
109
|
+
"max_retries": 1
|
|
110
|
+
},
|
|
111
|
+
"intention": {
|
|
112
|
+
"objective": "Define your objective here",
|
|
113
|
+
"success_criteria": "Define success criteria here"
|
|
114
|
+
},
|
|
115
|
+
"capabilities": []
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
// Write artifact
|
|
119
|
+
const content = JSON.stringify(template, null, 2);
|
|
120
|
+
fs.writeFileSync(filename, content);
|
|
121
|
+
console.log(`${C.green}✓ Created:${C.reset} ${filename}`);
|
|
122
|
+
|
|
123
|
+
// Generate integrity manifest
|
|
124
|
+
const sha256 = crypto.createHash('sha256').update(content).digest('hex');
|
|
125
|
+
const stats = fs.statSync(filename);
|
|
126
|
+
|
|
127
|
+
const manifest = {
|
|
128
|
+
"$schema": "https://josfox.ai/schemas/jos-manifest-0.0.7.json",
|
|
129
|
+
"manifest_version": "1.0.0",
|
|
130
|
+
"artifact_ref": filename,
|
|
131
|
+
"artifact_sha256": sha256,
|
|
132
|
+
"artifact_size_bytes": stats.size,
|
|
133
|
+
"timestamp": new Date().toISOString(),
|
|
134
|
+
"generated_by": "jos init command",
|
|
135
|
+
"canonical_version": "Format version v0.0.7 — Specification maturity v0.1.0 (Alpha)"
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const manifestPath = filename + '.sig.json';
|
|
139
|
+
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
|
|
140
|
+
console.log(`${C.green}✓ Created:${C.reset} ${manifestPath}`);
|
|
141
|
+
console.log(`${C.gray} SHA256: ${sha256}${C.reset}`);
|
|
142
|
+
|
|
143
|
+
console.log(`
|
|
144
|
+
${C.cyan}Next steps:${C.reset}
|
|
145
|
+
1. Edit ${filename} to define your tasks
|
|
146
|
+
2. Run: ${C.purple}jos validate ${filename}${C.reset}
|
|
147
|
+
3. Run: ${C.purple}jos run ${filename}${C.reset}
|
|
148
|
+
`);
|
|
149
|
+
|
|
150
|
+
// Log to witness
|
|
151
|
+
const runDir = path.join(home, 'runs', 'init-' + new Date().toISOString().replace(/[:.]/g, '-'));
|
|
152
|
+
if (!fs.existsSync(runDir)) fs.mkdirSync(runDir, { recursive: true });
|
|
153
|
+
|
|
154
|
+
const event = {
|
|
155
|
+
timestamp: new Date().toISOString(),
|
|
156
|
+
type: 'init:created',
|
|
157
|
+
artifact: filename,
|
|
158
|
+
manifest: manifestPath,
|
|
159
|
+
sha256: sha256
|
|
160
|
+
};
|
|
161
|
+
fs.appendFileSync(path.join(runDir, 'events.jsonl'), JSON.stringify(event) + '\n');
|
|
162
|
+
};
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JOS LLM Command - Execute artifacts via LLM
|
|
3
|
+
*/
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const AdapterFactory = require('../adapters');
|
|
7
|
+
const { calculateChecksum, verifyIntegrity } = require('../utils/crypto');
|
|
8
|
+
|
|
9
|
+
// AURORA colors
|
|
10
|
+
const C = {
|
|
11
|
+
reset: '\x1b[0m', bold: '\x1b[1m', dim: '\x1b[2m',
|
|
12
|
+
purple: '\x1b[38;5;135m', cyan: '\x1b[38;5;51m',
|
|
13
|
+
green: '\x1b[38;5;78m', red: '\x1b[38;5;196m',
|
|
14
|
+
yellow: '\x1b[38;5;220m', white: '\x1b[38;5;255m',
|
|
15
|
+
gray: '\x1b[38;5;245m', blue: '\x1b[38;5;39m'
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const DEFAULT_PROVIDER = 'https://api.josfox.cloud/prompts';
|
|
19
|
+
|
|
20
|
+
function getProviderConfig(home) {
|
|
21
|
+
const configPath = path.join(home, 'prompts', 'providers.json');
|
|
22
|
+
if (fs.existsSync(configPath)) {
|
|
23
|
+
return JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
providers: {
|
|
27
|
+
'josfox-cloud': { url: DEFAULT_PROVIDER, type: 'native', description: 'Official JOSFOX Cloud provider' }
|
|
28
|
+
},
|
|
29
|
+
default: 'josfox-cloud'
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function getApiKey(home) {
|
|
34
|
+
const secretsPath = path.join(home, 'secrets', 'vault.json');
|
|
35
|
+
if (fs.existsSync(secretsPath)) {
|
|
36
|
+
try {
|
|
37
|
+
const secrets = JSON.parse(fs.readFileSync(secretsPath, 'utf8'));
|
|
38
|
+
return secrets.JOSFOX_API_KEY || secrets.OPENAI_API_KEY || null;
|
|
39
|
+
} catch { return null; }
|
|
40
|
+
}
|
|
41
|
+
return process.env.JOSFOX_API_KEY || process.env.OPENAI_API_KEY || null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
exports.execute = async (args, home) => {
|
|
45
|
+
if (args.includes('--help') || args.length === 0) {
|
|
46
|
+
console.log(`
|
|
47
|
+
${C.purple}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${C.reset}
|
|
48
|
+
${C.bold}JOS LLM EXECUTION${C.reset} // Execute artifacts via LLM
|
|
49
|
+
${C.purple}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${C.reset}
|
|
50
|
+
|
|
51
|
+
${C.bold}Usage:${C.reset}
|
|
52
|
+
jos llm <artifact.jos|.fox> [options]
|
|
53
|
+
|
|
54
|
+
${C.bold}Options:${C.reset}
|
|
55
|
+
--model <name> Target model
|
|
56
|
+
--provider <url> API endpoint or Ollama URL
|
|
57
|
+
--type <native|ollama> Provider type
|
|
58
|
+
--production Enforce strict SHA integrity for .jos
|
|
59
|
+
|
|
60
|
+
${C.bold}Notes:${C.reset}
|
|
61
|
+
• .fox artifacts ALWAYS require valid SHA checksums.
|
|
62
|
+
• .jos artifacts require SHA only in --production mode.
|
|
63
|
+
`);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const target = args[0];
|
|
68
|
+
const absPath = path.resolve(target);
|
|
69
|
+
|
|
70
|
+
if (!fs.existsSync(absPath)) {
|
|
71
|
+
console.log(`${C.red}✖ File not found: ${target}${C.reset}`);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const ext = path.extname(absPath);
|
|
76
|
+
if (ext !== '.jos' && ext !== '.fox') {
|
|
77
|
+
console.log(`${C.red}✖ Invalid file type. Must be .jos or .fox${C.reset}`);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
console.log(`\n${C.cyan}${C.bold}JOS LLM EXECUTION${C.reset}`);
|
|
82
|
+
console.log(`${C.dim}Artifact: ${path.basename(absPath)}${C.reset}`);
|
|
83
|
+
|
|
84
|
+
// READ & PARSE
|
|
85
|
+
const rawContent = fs.readFileSync(absPath, 'utf8');
|
|
86
|
+
let artifact;
|
|
87
|
+
try {
|
|
88
|
+
artifact = JSON.parse(rawContent);
|
|
89
|
+
} catch (e) {
|
|
90
|
+
console.log(`${C.red}✖ Invalid JSON: ${e.message}${C.reset}`);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// INTEGRITY CHECK
|
|
95
|
+
const isProduction = args.includes('--production') || process.env.NODE_ENV === 'production';
|
|
96
|
+
const enforceSha = ext === '.fox' || isProduction;
|
|
97
|
+
|
|
98
|
+
if (enforceSha) {
|
|
99
|
+
// TODO: Strict canonical verification. For now, we check if meta.checksum exists.
|
|
100
|
+
if (!artifact.meta || !artifact.meta.checksum) {
|
|
101
|
+
console.log(`${C.red}✖ Integrity Check Failed: Missing checksum in ${ext} file${C.reset}`);
|
|
102
|
+
console.log(`${C.gray} (.fox files and production .jos require signed checksums)${C.reset}`);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
// const isValid = verifyIntegrity(artifact, rawContent); // Placeholder for strict check
|
|
106
|
+
// if (!isValid) { ... }
|
|
107
|
+
console.log(`${C.green}✓ Integrity Validated (Signature present)${C.reset}`);
|
|
108
|
+
} else {
|
|
109
|
+
console.log(`${C.yellow}⚠ Integrity Check Skipped (Dev Mode)${C.reset}`);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// RESOLVE PROVIDER
|
|
113
|
+
const config = getProviderConfig(home);
|
|
114
|
+
const providerKey = config.default;
|
|
115
|
+
const providerCfg = config.providers[providerKey] || config.providers['josfox-cloud'];
|
|
116
|
+
|
|
117
|
+
let providerUrl = providerCfg.url;
|
|
118
|
+
let providerType = providerCfg.type || 'native';
|
|
119
|
+
|
|
120
|
+
if (args.includes('--provider')) {
|
|
121
|
+
const pName = args[args.indexOf('--provider') + 1];
|
|
122
|
+
if (config.providers[pName]) {
|
|
123
|
+
providerUrl = config.providers[pName].url;
|
|
124
|
+
providerType = config.providers[pName].type || 'native';
|
|
125
|
+
} else {
|
|
126
|
+
providerUrl = pName;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if (args.includes('--type')) {
|
|
130
|
+
providerType = args[args.indexOf('--type') + 1];
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const model = args.includes('--model') ? args[args.indexOf('--model') + 1] : null;
|
|
134
|
+
const apiKey = getApiKey(home);
|
|
135
|
+
|
|
136
|
+
console.log(`${C.dim}Provider: ${providerUrl} (${providerType})${C.reset}`);
|
|
137
|
+
console.log(`${C.purple}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${C.reset}\n`);
|
|
138
|
+
|
|
139
|
+
// EXECUTE
|
|
140
|
+
const Adapter = AdapterFactory.getAdapter(providerType);
|
|
141
|
+
|
|
142
|
+
try {
|
|
143
|
+
console.log(`${C.yellow}⏳ Executing via LLM...${C.reset}`);
|
|
144
|
+
|
|
145
|
+
const result = await Adapter.execute(artifact, providerUrl, model, apiKey);
|
|
146
|
+
|
|
147
|
+
console.log(`\n${C.green}✓ Execution Complete${C.reset}`);
|
|
148
|
+
console.log(`${C.cyan}Status:${C.reset} ${result.status}`);
|
|
149
|
+
console.log(`\n${C.bold}Output:${C.reset}\n`);
|
|
150
|
+
console.log(result.output);
|
|
151
|
+
console.log('');
|
|
152
|
+
|
|
153
|
+
} catch (e) {
|
|
154
|
+
console.log(`${C.red}✖ Execution Failed: ${e.message}${C.reset}`);
|
|
155
|
+
if (e.message && e.message.includes('ECONNREFUSED')) {
|
|
156
|
+
console.log(`${C.gray} Is the provider running?${C.reset}`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
};
|