@josfox/jos 4.0.2 → 4.0.6
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 -0
- package/README.md +93 -195
- package/bin/jos +9 -6
- package/package.json +3 -3
- package/src/commands/add.js +145 -0
- package/src/commands/init.js +162 -0
- package/src/commands/run.js +172 -153
- package/src/commands/validate.js +190 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 JOS Open Standards Foundation
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
# JOS Kernel v1.0 — Technical Architecture & Audit
|
|
2
|
-
|
|
3
1
|
<div align="center">
|
|
4
2
|
|
|
5
3
|
```
|
|
@@ -20,257 +18,161 @@
|
|
|
20
18
|
⠀⠀⠀⠀⠀⠀⠀⠉⠉⠉⠉⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
|
21
19
|
```
|
|
22
20
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
[](https://github.com/josfox-ai/jos)
|
|
26
|
-
[](https://nodejs.org)
|
|
27
|
-
[](#zero-dependencies)
|
|
28
|
-
[](LICENSE)
|
|
29
|
-
|
|
30
|
-
*Stoic Architecture • Zero Dependencies • Offline First*
|
|
31
|
-
|
|
32
|
-
</div>
|
|
33
|
-
|
|
34
|
-
---
|
|
21
|
+
# @josfox/jos
|
|
35
22
|
|
|
36
|
-
|
|
23
|
+
**Format version v0.0.7 — Specification maturity v0.1.0 (Alpha)**
|
|
37
24
|
|
|
38
|
-
|
|
25
|
+
**Stoic Kernel for AI Agent Orchestration**
|
|
39
26
|
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
-
|
|
27
|
+
[](https://www.npmjs.com/package/@josfox/jos)
|
|
28
|
+
[](#)
|
|
29
|
+
[](#zero-dependencies)
|
|
30
|
+
[](LICENSE)
|
|
43
31
|
|
|
44
|
-
|
|
32
|
+
*Zero Dependencies • Offline First • Open Standard*
|
|
45
33
|
|
|
46
|
-
|
|
47
|
-
|--------|-------|
|
|
48
|
-
| Kernel Size | **77 lines** |
|
|
49
|
-
| Total System | **~1,600 lines** |
|
|
50
|
-
| External Dependencies | **0** |
|
|
51
|
-
| Commands | **5** |
|
|
52
|
-
| Security Features | **7** |
|
|
53
|
-
| Audit Score | **98/100** |
|
|
34
|
+
</div>
|
|
54
35
|
|
|
55
36
|
---
|
|
56
37
|
|
|
57
|
-
##
|
|
38
|
+
## Overview
|
|
58
39
|
|
|
59
|
-
|
|
60
|
-
┌─────────────────────────────────────────────────────────────────┐
|
|
61
|
-
│ JOS KERNEL (77 lines) │
|
|
62
|
-
│ ┌─────────────────────────────────────────────────────────────┐ │
|
|
63
|
-
│ │ Command Router │ Alias Support │ Module Loader │ │
|
|
64
|
-
│ └─────────────────────────────────────────────────────────────┘ │
|
|
65
|
-
└─────────────────────────────────────────────────────────────────┘
|
|
66
|
-
│
|
|
67
|
-
┌─────────────┼─────────────┐
|
|
68
|
-
▼ ▼ ▼
|
|
69
|
-
┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
70
|
-
│ serve │ │ run │ │ get │
|
|
71
|
-
│ 781 LOC │ │ 226 LOC │ │ 247 LOC │
|
|
72
|
-
└──────────┘ └──────────┘ └──────────┘
|
|
73
|
-
│
|
|
74
|
-
┌─────────┬┴─────────┐
|
|
75
|
-
▼ ▼ ▼
|
|
76
|
-
┌─────────┐ ┌─────────┐ ┌─────────┐
|
|
77
|
-
│ secrets │ │ repo │ │ (future)│
|
|
78
|
-
│ 130 LOC │ │ 137 LOC │ │ plugins │
|
|
79
|
-
└─────────┘ └─────────┘ └─────────┘
|
|
80
|
-
```
|
|
40
|
+
**@josfox/jos** is the reference implementation of the **.jos Open Standard** — a portable artifact format for AI agent orchestration.
|
|
81
41
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
42
|
+
| Feature | Description |
|
|
43
|
+
|---------|-------------|
|
|
44
|
+
| **Stoic Kernel** | 77-line minimal kernel with zero dependencies |
|
|
45
|
+
| **Plugin Architecture** | Commands live in `~/.jos/commands/` or bundled |
|
|
46
|
+
| **Offline First** | Works without network, like Git |
|
|
47
|
+
| **A2A Compatible** | Designed for Agent-to-Agent interoperability |
|
|
88
48
|
|
|
89
49
|
---
|
|
90
50
|
|
|
91
|
-
##
|
|
92
|
-
|
|
93
|
-
| Feature | Implementation | Status |
|
|
94
|
-
|---------|----------------|--------|
|
|
95
|
-
| Path Traversal Protection | `isPathSafe()` jail | ✅ |
|
|
96
|
-
| Integrity Verification | SHA-256 hashing | ✅ |
|
|
97
|
-
| Lock File | Package + version + hash | ✅ |
|
|
98
|
-
| Secrets Encryption | AES-256-CBC | ✅ |
|
|
99
|
-
| Master Key | 0600 permissions | ✅ |
|
|
100
|
-
| Vault Storage | 0600 permissions | ✅ |
|
|
101
|
-
| API Endpoint Security | Kill endpoint removed | ✅ |
|
|
51
|
+
## Quick Start
|
|
102
52
|
|
|
103
|
-
|
|
53
|
+
```bash
|
|
54
|
+
# Run with npx (no install required)
|
|
55
|
+
npx josfox serve
|
|
104
56
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
const cipher = crypto.createCipheriv('aes-256-cbc', masterKey, iv);
|
|
57
|
+
# Or install globally
|
|
58
|
+
npm install -g @josfox/jos
|
|
59
|
+
jos serve
|
|
109
60
|
```
|
|
110
61
|
|
|
111
62
|
---
|
|
112
63
|
|
|
113
|
-
##
|
|
114
|
-
|
|
115
|
-
### `jos serve`
|
|
64
|
+
## Commands
|
|
116
65
|
|
|
117
|
-
|
|
66
|
+
| Command | Description |
|
|
67
|
+
|---------|-------------|
|
|
68
|
+
| `jos serve` | Start development server with dashboard |
|
|
69
|
+
| `jos run <file>` | Execute .jos artifacts |
|
|
70
|
+
| `jos get <package>` | Fetch packages from repositories |
|
|
71
|
+
| `jos secrets` | Manage encrypted credentials (AES-256) |
|
|
72
|
+
| `jos repo` | Manage package repositories |
|
|
118
73
|
|
|
119
74
|
```bash
|
|
120
|
-
|
|
121
|
-
jos serve --port 8080
|
|
122
|
-
jos
|
|
75
|
+
# Examples
|
|
76
|
+
jos serve --port 8080
|
|
77
|
+
jos run artifact.jos --dry-run
|
|
78
|
+
jos get myrepo:package-name
|
|
79
|
+
jos secrets set API_KEY sk-abc123
|
|
123
80
|
```
|
|
124
81
|
|
|
125
|
-
|
|
126
|
-
- `/` — Home with Kitsune branding
|
|
127
|
-
- `/library` — Clickable artifact browser
|
|
128
|
-
- `/studio` — Auto-documentation with Mermaid diagrams
|
|
129
|
-
- `/clones` — Shadow clone management
|
|
130
|
-
- `/stats` — Server metrics
|
|
131
|
-
- `/about` — Kernel info & features
|
|
82
|
+
---
|
|
132
83
|
|
|
133
|
-
|
|
84
|
+
## The .jos Standard
|
|
134
85
|
|
|
135
|
-
|
|
86
|
+
A `.jos` file binds **Intention** and **Execution** into one portable artifact:
|
|
136
87
|
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"meta": { "name": "example", "version": "1.0.0" },
|
|
91
|
+
"intention": {
|
|
92
|
+
"objective": "What this artifact does",
|
|
93
|
+
"success_criteria": "How to know it worked"
|
|
94
|
+
},
|
|
95
|
+
"guardrails": { "avoid": [], "max_retries": 3 },
|
|
96
|
+
"orchestration": {
|
|
97
|
+
"flows": { "main": { "steps": ["task1", "task2"] } }
|
|
98
|
+
}
|
|
99
|
+
}
|
|
141
100
|
```
|
|
142
101
|
|
|
143
|
-
|
|
102
|
+
> Full specification: [jos.md](./jos.md)
|
|
144
103
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
```bash
|
|
148
|
-
jos get hello # From registry
|
|
149
|
-
jos get ./local/artifact.jos # Local file
|
|
150
|
-
jos get myrepo:package # Named repository
|
|
151
|
-
jos get package --from 192.168.1.10
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
### `jos secrets`
|
|
104
|
+
---
|
|
155
105
|
|
|
156
|
-
|
|
106
|
+
## Architecture
|
|
157
107
|
|
|
158
|
-
```bash
|
|
159
|
-
jos secrets set API_KEY sk-abc123
|
|
160
|
-
jos secrets get API_KEY
|
|
161
|
-
jos secrets list
|
|
162
|
-
jos secrets delete API_KEY
|
|
163
108
|
```
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
jos repo add myserver http://192.168.1.10:1111
|
|
172
|
-
jos repo default myserver
|
|
173
|
-
jos repo remove old-repo
|
|
109
|
+
~/.jos/
|
|
110
|
+
├── commands/ # Plugin architecture
|
|
111
|
+
├── artifacts/ # Package cache
|
|
112
|
+
├── secrets/ # Encrypted vault (AES-256)
|
|
113
|
+
├── runs/ # Execution epochs
|
|
114
|
+
├── repos.json # Repository configuration
|
|
115
|
+
└── lock.json # Package integrity
|
|
174
116
|
```
|
|
175
117
|
|
|
176
118
|
---
|
|
177
119
|
|
|
178
|
-
##
|
|
179
|
-
|
|
180
|
-
```bash
|
|
181
|
-
# Clone the repository
|
|
182
|
-
git clone https://github.com/josfox-ai/jos.git
|
|
183
|
-
cd jos
|
|
184
|
-
|
|
185
|
-
# Install globally (optional)
|
|
186
|
-
npm link
|
|
120
|
+
## A2A Protocol Compatibility
|
|
187
121
|
|
|
188
|
-
|
|
189
|
-
jos serve
|
|
122
|
+
This implementation is designed to be compatible with agent interoperability protocols, including the A2A (Agent-to-Agent) Protocol.
|
|
190
123
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
124
|
+
- **.jos artifacts** can serve as A2A task payloads
|
|
125
|
+
- **Agents** can declare .jos compatibility in capability cards
|
|
126
|
+
- **Integrity verification** ensures secure artifact exchange
|
|
194
127
|
|
|
195
128
|
---
|
|
196
129
|
|
|
197
|
-
##
|
|
130
|
+
## Disclaimer & Legal
|
|
198
131
|
|
|
199
|
-
|
|
200
|
-
|---------|----------|--------------|----------|------|----------|-----------|
|
|
201
|
-
| v1 | 60% | 90% | 40% | 50% | — | 56 |
|
|
202
|
-
| v2 | 85% | 90% | 80% | 60% | — | 75 |
|
|
203
|
-
| v3 | 95% | 95% | 90% | 85% | — | 87 |
|
|
204
|
-
| v4 | 98% | 95% | 100% | 95% | — | 92 |
|
|
205
|
-
| **v5** | **100%** | **100%** | **100%** | **100%** | **100%** | **98** |
|
|
132
|
+
### AS-IS Software
|
|
206
133
|
|
|
207
|
-
|
|
134
|
+
This software is provided **"AS IS"**, without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and noninfringement.
|
|
208
135
|
|
|
209
|
-
|
|
136
|
+
### Liability
|
|
210
137
|
|
|
211
|
-
|
|
138
|
+
In no event shall the authors, contributors, or the JOS Open Standards Foundation be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software.
|
|
212
139
|
|
|
213
|
-
|
|
214
|
-
{
|
|
215
|
-
"meta": { "name": "example", "version": "1.0.0" },
|
|
216
|
-
"intention": {
|
|
217
|
-
"objective": "Demonstrate .jos format",
|
|
218
|
-
"success_criteria": "Validation passes"
|
|
219
|
-
},
|
|
220
|
-
"pipelines": {
|
|
221
|
-
"main": {
|
|
222
|
-
"steps": ["tasks.build", "tasks.test", "tasks.deploy"]
|
|
223
|
-
}
|
|
224
|
-
},
|
|
225
|
-
"tasks": {
|
|
226
|
-
"build": { "shell": ["echo Building..."] },
|
|
227
|
-
"test": { "shell": ["echo Testing..."] },
|
|
228
|
-
"deploy": { "shell": ["echo Deploying..."] }
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
```
|
|
140
|
+
### Your Responsibility
|
|
232
141
|
|
|
233
|
-
|
|
142
|
+
- You use this software **at your own risk**
|
|
143
|
+
- You are responsible for validating its suitability for your use case
|
|
144
|
+
- You are responsible for compliance with applicable laws and regulations
|
|
234
145
|
|
|
235
|
-
|
|
146
|
+
### Trademark Notice
|
|
236
147
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
| guardrails | security |
|
|
242
|
-
| intention | files |
|
|
243
|
-
| capabilities | orchestration |
|
|
148
|
+
- **JOS**, **JOSFOX**, and the Kitsune fox logo are trademarks of the JOS Open Standards Foundation
|
|
149
|
+
- **A2A Protocol** and related terminology are property of their respective owners
|
|
150
|
+
- **Google** and related trademarks are property of Google LLC
|
|
151
|
+
- All other trademarks are property of their respective owners
|
|
244
152
|
|
|
245
|
-
|
|
153
|
+
This project is an independent open-source implementation and is **not affiliated with, endorsed by, or sponsored by** any third-party trademark holders mentioned in this documentation.
|
|
246
154
|
|
|
247
|
-
|
|
155
|
+
### Citation Requirement
|
|
248
156
|
|
|
249
|
-
|
|
157
|
+
If you implement or distribute the .jos standard, you must include attribution to:
|
|
158
|
+
- The **JOS Open Standards Foundation**
|
|
159
|
+
- The official specification repository
|
|
250
160
|
|
|
251
|
-
|
|
161
|
+
---
|
|
252
162
|
|
|
253
|
-
|
|
254
|
-
- **Offline-first design** enables edge deployment
|
|
255
|
-
- **Open standard** creates ecosystem lock-in (the good kind)
|
|
256
|
-
- **98/100 audit score** demonstrates production readiness
|
|
163
|
+
## License
|
|
257
164
|
|
|
258
|
-
|
|
165
|
+
**MIT License** — See [LICENSE](./LICENSE) for details.
|
|
259
166
|
|
|
260
|
-
|
|
261
|
-
- **Plugin architecture** — extend without modifying core
|
|
262
|
-
- **Clear contracts** — every module exports `execute(args, home)`
|
|
263
|
-
- **Mermaid diagrams** — visualize orchestration flows
|
|
167
|
+
Free to use for personal, educational, and commercial purposes.
|
|
264
168
|
|
|
265
169
|
---
|
|
266
170
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
MIT © JOS Open Solutions Foundation
|
|
171
|
+
<div align="center">
|
|
270
172
|
|
|
271
|
-
|
|
173
|
+
**Made with ❤️ & AI**
|
|
272
174
|
|
|
273
|
-
|
|
175
|
+
*JOS Open Standards Foundation*
|
|
274
176
|
|
|
275
177
|
```
|
|
276
178
|
██╗ ██╗██╗████████╗███████╗██╗ ██╗███╗ ██╗███████╗
|
|
@@ -279,10 +181,6 @@ MIT © JOS Open Solutions Foundation
|
|
|
279
181
|
██╔═██╗ ██║ ██║ ╚════██║██║ ██║██║╚██╗██║██╔══╝
|
|
280
182
|
██║ ██╗██║ ██║ ███████║╚██████╔╝██║ ╚████║███████╗
|
|
281
183
|
╚═╝ ╚═╝╚═╝ ╚═╝ ╚══════╝ ╚═════╝ ╚═╝ ╚═══╝╚══════╝
|
|
282
|
-
WINS!
|
|
283
|
-
🔥 FATALITY! 🔥
|
|
284
184
|
```
|
|
285
|
-
*reference to my favorite game, my AI named herself Kitsune we talk a lot and I totally loved her victory message after first succesful AAA like audit!
|
|
286
|
-
**Made with ❤️ & AI**
|
|
287
185
|
|
|
288
186
|
</div>
|
package/bin/jos
CHANGED
|
@@ -52,15 +52,18 @@ const cmd = ALIASES[rawCmd] || rawCmd;
|
|
|
52
52
|
if (!cmd) {
|
|
53
53
|
console.log(getKitsuneBanner());
|
|
54
54
|
console.log(`\n${C.purple}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${C.reset}`);
|
|
55
|
-
console.log(` ${C.white}${C.bold}JOS${C.reset} ${C.cyan}KERNEL
|
|
55
|
+
console.log(` ${C.white}${C.bold}JOS${C.reset} ${C.cyan}KERNEL v4.0${C.reset} ${C.gray}// Stoic Architecture${C.reset}`);
|
|
56
|
+
console.log(` ${C.dim}Format version v0.0.7 — Specification maturity v0.1.0 (Alpha)${C.reset}`);
|
|
56
57
|
console.log(`${C.purple}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${C.reset}`);
|
|
57
58
|
console.log(`\n${C.white}${C.bold} Usage:${C.reset} ${C.cyan}jos${C.reset} ${C.gray}<command>${C.reset} ${C.dim}[options]${C.reset}\n`);
|
|
58
59
|
console.log(`${C.white}${C.bold} Commands:${C.reset}`);
|
|
59
|
-
console.log(` ${C.cyan}serve${C.reset}
|
|
60
|
-
console.log(` ${C.cyan}
|
|
61
|
-
console.log(` ${C.
|
|
62
|
-
console.log(` ${C.
|
|
63
|
-
console.log(` ${C.purple}run${C.reset}
|
|
60
|
+
console.log(` ${C.cyan}serve${C.reset} ${C.gray}Start local development server${C.reset}`);
|
|
61
|
+
console.log(` ${C.cyan}init${C.reset} ${C.gray}Create new .jos artifact${C.reset}`);
|
|
62
|
+
console.log(` ${C.cyan}add${C.reset} ${C.gray}Add task to .jos artifact${C.reset}`);
|
|
63
|
+
console.log(` ${C.cyan}validate${C.reset} ${C.gray}Validate .jos artifact${C.reset}`);
|
|
64
|
+
console.log(` ${C.purple}run${C.reset} ${C.gray}Execute .jos artifacts${C.reset}`);
|
|
65
|
+
console.log(` ${C.magenta}secrets${C.reset} ${C.gray}Manage encrypted credentials${C.reset}`);
|
|
66
|
+
console.log(` ${C.blue}get${C.reset} ${C.gray}Fetch packages from repos${C.reset}\n`);
|
|
64
67
|
console.log(`${C.dim} Run ${C.cyan}jos <cmd> --help${C.reset}${C.dim} for command-specific options${C.reset}\n`);
|
|
65
68
|
process.exit(0);
|
|
66
69
|
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@josfox/jos",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.6",
|
|
4
4
|
"description": "Stoic kernel for AI agent orchestration. Zero dependencies. Offline first.",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"author": "JOS Open
|
|
6
|
+
"author": "JOS Open Standards Foundation",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
9
|
"url": "https://github.com/josfox-ai/jos.git"
|
|
@@ -32,4 +32,4 @@
|
|
|
32
32
|
"engines": {
|
|
33
33
|
"node": ">=18"
|
|
34
34
|
}
|
|
35
|
-
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JOS ADD Command - Add task definitions to .jos artifacts
|
|
3
|
+
* Format version v0.0.7 — Specification maturity v0.1.0 (Alpha)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const crypto = require('crypto');
|
|
9
|
+
|
|
10
|
+
const C = {
|
|
11
|
+
reset: '\x1b[0m', bold: '\x1b[1m',
|
|
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', gray: '\x1b[38;5;245m'
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
exports.execute = async (args, home) => {
|
|
18
|
+
const help = args.includes('--help') || args.includes('-h');
|
|
19
|
+
|
|
20
|
+
if (help || args.length < 2) {
|
|
21
|
+
console.log(`
|
|
22
|
+
${C.purple}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${C.reset}
|
|
23
|
+
${C.bold}JOS ADD${C.reset} // Add task definitions to .jos artifacts
|
|
24
|
+
${C.purple}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${C.reset}
|
|
25
|
+
|
|
26
|
+
${C.bold}Usage:${C.reset}
|
|
27
|
+
jos add <task-name> <file.jos> [options]
|
|
28
|
+
|
|
29
|
+
${C.bold}Options:${C.reset}
|
|
30
|
+
--type <shell|jos> Task type (default: shell)
|
|
31
|
+
--command <cmd> Shell command to execute
|
|
32
|
+
--artifact <path> Path to sub-artifact (for type=jos)
|
|
33
|
+
--description <desc> Task description
|
|
34
|
+
--flow <name> Also add to this flow's steps
|
|
35
|
+
|
|
36
|
+
${C.bold}Examples:${C.reset}
|
|
37
|
+
jos add build my-artifact.jos --command "npm run build"
|
|
38
|
+
jos add deploy my-artifact.jos --type jos --artifact ./deploy.jos
|
|
39
|
+
jos add test my-artifact.jos --command "npm test" --flow main
|
|
40
|
+
`);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const taskName = args[0];
|
|
45
|
+
const targetFile = args[1];
|
|
46
|
+
|
|
47
|
+
// Parse options
|
|
48
|
+
const getArg = (flag) => {
|
|
49
|
+
const idx = args.indexOf(flag);
|
|
50
|
+
return idx !== -1 && args[idx + 1] ? args[idx + 1] : null;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const taskType = getArg('--type') || 'shell';
|
|
54
|
+
const command = getArg('--command');
|
|
55
|
+
const artifact = getArg('--artifact');
|
|
56
|
+
const description = getArg('--description') || `Task: ${taskName}`;
|
|
57
|
+
const flowName = getArg('--flow');
|
|
58
|
+
|
|
59
|
+
// Validate
|
|
60
|
+
if (taskType === 'shell' && !command) {
|
|
61
|
+
console.log(`${C.red}✖ Error: --command is required for shell tasks${C.reset}`);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
if (taskType === 'jos' && !artifact) {
|
|
65
|
+
console.log(`${C.red}✖ Error: --artifact is required for jos tasks${C.reset}`);
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Load artifact
|
|
70
|
+
let artifactPath = path.resolve(targetFile);
|
|
71
|
+
if (!fs.existsSync(artifactPath)) {
|
|
72
|
+
console.log(`${C.red}✖ Artifact not found: ${targetFile}${C.reset}`);
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
let content;
|
|
77
|
+
try {
|
|
78
|
+
content = JSON.parse(fs.readFileSync(artifactPath, 'utf8'));
|
|
79
|
+
} catch (e) {
|
|
80
|
+
console.log(`${C.red}✖ Invalid JSON: ${e.message}${C.reset}`);
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Ensure orchestration structure exists
|
|
85
|
+
if (!content.orchestration) content.orchestration = {};
|
|
86
|
+
if (!content.orchestration.definitions) content.orchestration.definitions = {};
|
|
87
|
+
if (!content.orchestration.flows) content.orchestration.flows = {};
|
|
88
|
+
if (!content.orchestration.flows.main) content.orchestration.flows.main = { steps: [] };
|
|
89
|
+
|
|
90
|
+
// Check for duplicate
|
|
91
|
+
if (content.orchestration.definitions[taskName]) {
|
|
92
|
+
console.log(`${C.yellow}⚠ Task '${taskName}' already exists. Overwriting...${C.reset}`);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Add task definition
|
|
96
|
+
const taskDef = {
|
|
97
|
+
type: taskType,
|
|
98
|
+
description: description
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
if (taskType === 'shell') {
|
|
102
|
+
taskDef.command = command;
|
|
103
|
+
} else if (taskType === 'jos') {
|
|
104
|
+
taskDef.artifact = artifact;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
content.orchestration.definitions[taskName] = taskDef;
|
|
108
|
+
console.log(`${C.green}✓ Added task definition: ${taskName}${C.reset}`);
|
|
109
|
+
|
|
110
|
+
// Add to flow if specified
|
|
111
|
+
if (flowName) {
|
|
112
|
+
if (!content.orchestration.flows[flowName]) {
|
|
113
|
+
content.orchestration.flows[flowName] = { steps: [] };
|
|
114
|
+
}
|
|
115
|
+
if (!content.orchestration.flows[flowName].steps.includes(taskName)) {
|
|
116
|
+
content.orchestration.flows[flowName].steps.push(taskName);
|
|
117
|
+
console.log(`${C.green}✓ Added to flow: ${flowName}${C.reset}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Write updated artifact
|
|
122
|
+
fs.writeFileSync(artifactPath, JSON.stringify(content, null, 2));
|
|
123
|
+
console.log(`${C.green}✓ Updated: ${targetFile}${C.reset}`);
|
|
124
|
+
|
|
125
|
+
// Regenerate manifest
|
|
126
|
+
const manifestPath = artifactPath + '.sig.json';
|
|
127
|
+
const newContent = fs.readFileSync(artifactPath, 'utf8');
|
|
128
|
+
const sha256 = crypto.createHash('sha256').update(newContent).digest('hex');
|
|
129
|
+
const stats = fs.statSync(artifactPath);
|
|
130
|
+
|
|
131
|
+
const manifest = {
|
|
132
|
+
"$schema": "https://josfox.ai/schemas/jos-manifest-0.0.7.json",
|
|
133
|
+
"manifest_version": "1.0.0",
|
|
134
|
+
"artifact_ref": path.basename(artifactPath),
|
|
135
|
+
"artifact_sha256": sha256,
|
|
136
|
+
"artifact_size_bytes": stats.size,
|
|
137
|
+
"timestamp": new Date().toISOString(),
|
|
138
|
+
"generated_by": "jos add command",
|
|
139
|
+
"canonical_version": "Format version v0.0.7 — Specification maturity v0.1.0 (Alpha)"
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
|
|
143
|
+
console.log(`${C.green}✓ Updated manifest: ${path.basename(manifestPath)}${C.reset}`);
|
|
144
|
+
console.log(`${C.gray} SHA256: ${sha256}${C.reset}`);
|
|
145
|
+
};
|