-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmanifest.jps
More file actions
211 lines (196 loc) · 8.63 KB
/
manifest.jps
File metadata and controls
211 lines (196 loc) · 8.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
type: install
version: 0.1.0
id: constructor-fabric
baseUrl: https://raw.githubusercontent.com/jelastic-jps/constructor-fabric/main/
name: Constructor Fabric
logo: assets/constructor-fabric-logo.png
categories:
- apps/dev-and-admin-tools
- apps/collaboration
- apps/productivity
description:
text: Constructor Fabric environment with a local PRD -> features -> tasks pipeline and OpenAI/Claude LLM configuration.
short: Constructor Fabric
targetRegions:
type: vz7
ssl: true
skipNodeEmails: true
globals:
VNC_PASSWORD: ${fn.password(16)}
CF_PORT: 8081
APP_PORT: 8081
LLM_PROVIDER: openai
OPENAI_MODEL: gpt-5.5
CLAUDE_MODEL: claude-3-5-sonnet-latest
RESOLUTION: 1280x720
SCRIPT_VERSION: github-assets-20260529-1
CF_SOURCE_REF: 851ab1423cf04c3f91bdc6ad72a883964a95736a
settings:
fields:
- caption: LLM provider
type: list
inputType: string
name: llm-provider
default: openai
values:
openai: OpenAI
claude: Claude
tooltip: Select which LLM provider the Constructor Fabric workflow should use.
showIf:
openai:
- caption: OpenAI model
type: list
inputType: string
name: openai-model
default: gpt-5.5
values:
gpt-5.5: OpenAI GPT-5.5
gpt-5.4: OpenAI GPT-5.4
gpt-5.4-mini: OpenAI GPT-5.4 mini
gpt-5.4-nano: OpenAI GPT-5.4 nano
tooltip: Select the OpenAI model used by the Constructor Fabric workflow.
claude:
- caption: Anthropic model
type: list
inputType: string
name: claude-model
default: claude-3-5-sonnet-latest
values:
claude-3-5-sonnet-latest: Claude 3.5 Sonnet latest
claude-3-7-sonnet-latest: Claude 3.7 Sonnet latest
claude-sonnet-4-20250514: Claude Sonnet 4
claude-opus-4-20250514: Claude Opus 4
tooltip: Select the Anthropic Claude model used by the Constructor Fabric workflow.
- caption: API Token
type: string
inputType: password
name: api-token
value: ""
required: false
tooltip: API token for the selected provider. Use an OpenAI key for openai or an Anthropic/Claude key for claude.
nodes:
- image: ihorman/constructor-fabric:latest
nodeType: docker
displayName: Constructor Fabric
cloudlets: 16
nodeGroup: cp
ports:
- 80
- 5900
endpoints:
- name: VNC
privatePort: 5900
protocol: TCP
env:
TZ: Europe/Kyiv
USER: root
PASSWORD: ${globals.VNC_PASSWORD}
VNC_PASSWORD: ${globals.VNC_PASSWORD}
HTTP_PASSWORD: ${globals.VNC_PASSWORD}
LLM_PROVIDER: ${settings.llm-provider}
API_TOKEN: ${settings.api-token}
OPENAI_API_KEY: ${settings.api-token}
ANTHROPIC_API_KEY: ${settings.api-token}
OPENAI_MODEL: ${settings.openai-model:gpt-5.5}
CLAUDE_MODEL: ${settings.claude-model:claude-3-5-sonnet-latest}
CF_IDE_PROFILE: all
CF_PREINSTALLED_IDES: 1
CF_HOME: /root/constructor-fabric
CF_PORT: ${globals.CF_PORT}
ALSADEV: default
PULSE_RUNTIME_PATH: /tmp/pulse-root
PULSE_SERVER: unix:/tmp/pulse-root/native
SDL_AUDIODRIVER: pulse
AUDIODEV: default
NO_PROXY: localhost,127.0.0.1,::1
no_proxy: localhost,127.0.0.1,::1
JELASTIC_EXPOSE: 80
JELASTIC_PORTS: 80
RESOLUTION: 1280x720
SCRIPT_VERSION: ${globals.SCRIPT_VERSION}
CF_SOURCE_REF: ${globals.CF_SOURCE_REF}
onInstall:
- bootstrap
- verify
actions:
bootstrap:
- cmd[cp]: |-
set -euo pipefail
export DEBIAN_FRONTEND=noninteractive
mkdir -p /root/constructor-fabric
curl --noproxy '*' -fsSL "https://raw.githubusercontent.com/jelastic-jps/constructor-fabric/${globals.CF_SOURCE_REF}/scripts/bootstrap.sh?v=${globals.SCRIPT_VERSION}" -o /root/constructor-fabric/bootstrap.sh
chmod +x /root/constructor-fabric/bootstrap.sh
/root/constructor-fabric/bootstrap.sh
verify:
- cmd[cp]: |-
set -euo pipefail
export NO_PROXY=localhost,127.0.0.1,::1
export no_proxy=$NO_PROXY
app_ready=0
for i in $(seq 1 60); do
if curl --noproxy '*' -fsS http://127.0.0.1:8081/health >/dev/null; then
echo 'Constructor Fabric app is up'
curl --noproxy '*' -fsS http://127.0.0.1:8081/health
app_ready=1
break
fi
sleep 2
done
if [ "$app_ready" != "1" ]; then
echo 'Constructor Fabric app did not become ready in time' >&2
exit 1
fi
python3 -c 'import socket,sys; checks=[("127.0.0.1",5900,"native-vnc"),("127.0.0.1",6081,"websockify")];
import time
for host,port,name in checks:
last=None
for _ in range(30):
try:
s=socket.create_connection((host,port),timeout=2)
if port==5900:
banner=s.recv(12).decode(errors="replace").strip()
assert banner.startswith("RFB"), banner
s.close(); print(f"{name} is up on {host}:{port}"); break
except Exception as exc:
last=exc; time.sleep(2)
else:
print(f"{name} did not become ready: {last}", file=sys.stderr); sys.exit(1)'
test -f /root/Desktop/Chromium.desktop || { echo 'Chromium desktop launcher missing' >&2; exit 1; }
grep -q '^Name=Chromium$' /root/Desktop/Chromium.desktop || { echo 'Chromium desktop launcher has wrong label' >&2; exit 1; }
grep -q '^Exec=/usr/local/bin/constructor-fabric-chromium' /root/Desktop/Chromium.desktop || { echo 'Chromium desktop launcher has wrong Exec' >&2; exit 1; }
test -x /usr/local/bin/constructor-fabric-chromium || { echo 'Chromium wrapper missing' >&2; exit 1; }
test -f /root/Desktop/Terminal.desktop || { echo 'Terminal desktop launcher missing' >&2; exit 1; }
if command -v firefox >/dev/null 2>&1 || command -v firefox-esr >/dev/null 2>&1; then echo 'Firefox is still installed' >&2; exit 1; fi
echo 'Chromium and Terminal desktop launchers are present and Firefox is absent'
cd /root/cyber-constructor
cfc --version
cfc info --json | python3 -c 'import json,sys; data=json.load(sys.stdin); assert data["status"] == "FOUND", data; assert data["relative_path"] == ".cf-constructor", data; print("cyber-constructor info is FOUND at .cf-constructor")'
cfc validate --json | python3 -c 'import json,sys; data=json.load(sys.stdin); assert data["status"] == "PASS", data; print("cyber-constructor validate is PASS")'
cfc agents --json | python3 -c 'import json,sys; data=json.load(sys.stdin); assert data["status"] == "OK", data; text=json.dumps(data).lower(); required=["windsurf","cursor","claude","copilot","openai"]; missing=[x for x in required if x not in text]; assert not missing, {"missing": missing, "data": data}; print("cyber-constructor agents are OK for "+", ".join(required))'
success: |
<h3>Constructor Fabric is ready</h3>
<h4>Access</h4>
<p>
<a href="https://${env.domain}/" target="_blank">Open Constructor Fabric noVNC desktop</a>
</p>
<h4>VNC password</h4>
<p>Use this password if noVNC asks for it:</p>
<input type="text" readonly="readonly" value="${globals.VNC_PASSWORD}" style="width: 100%; max-width: 420px; font-family: monospace; padding: 6px;" onclick="this.select();" />
<h4>Desktop contents</h4>
<ul>
<li>noVNC opens the Constructor Fabric desktop at 1280x720.</li>
<li>The bottom LXDE panel contains launchers, clock, tray, and task switcher.</li>
<li>The Constructor Fabric Trainer opens as an Electron desktop app with copy-ready prompts.</li>
<li>The desktop is intentionally minimal: Trainer, Chromium, Terminal Emulator, VS Code, Cursor, and Windsurf only.</li>
<li>Firefox is removed; the Chromium launcher runs the container-safe browser directly.</li>
<li>Claude/Codex integrations are generated inside the workspace for those IDEs; no misleading terminal-only IDE icons are shown.</li>
</ul>
<h4>Workspace</h4>
<p><code>/root/workspaces/constructor-fabric-workspace</code></p>
<h4>Install options used</h4>
<table>
<tr><td>LLM provider</td><td><code>${settings.llm-provider}</code></td></tr>
<tr><td>Model</td><td><code>${settings.openai-model:}${settings.claude-model:}</code></td></tr>
<tr><td>API Token</td><td>configured from install form when provided</td></tr>
</table>
<p>If you set an API Token in the install form, Constructor Fabric exports it into the generated workspace environment.</p>