Compare commits
3 Commits
feat/a11y-
...
fix/add-sm
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9854501bbd | ||
|
|
68ee64866a | ||
|
|
e6d0df40b4 |
24
.gitea/workflows/smoke.yml
Normal file
24
.gitea/workflows/smoke.yml
Normal file
@@ -0,0 +1,24 @@
|
||||
name: Smoke Test
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches: [main]
|
||||
jobs:
|
||||
smoke:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
- name: Parse check
|
||||
run: |
|
||||
find . -name '*.yml' -o -name '*.yaml' | grep -v .gitea | xargs -r python3 -c "import sys,yaml; [yaml.safe_load(open(f)) for f in sys.argv[1:]]"
|
||||
find . -name '*.json' | xargs -r python3 -m json.tool > /dev/null
|
||||
find . -name '*.py' | xargs -r python3 -m py_compile
|
||||
find . -name '*.sh' | xargs -r bash -n
|
||||
echo "PASS: All files parse"
|
||||
- name: Secret scan
|
||||
run: |
|
||||
if grep -rE 'sk-or-|sk-ant-|ghp_|AKIA' . --include='*.yml' --include='*.py' --include='*.sh' 2>/dev/null | grep -v .gitea; then exit 1; fi
|
||||
echo "PASS: No secrets"
|
||||
46
game.js
46
game.js
@@ -425,6 +425,22 @@ const PDEFS = [
|
||||
trigger: () => G.totalCompute >= 20000,
|
||||
effect: () => { G.computeBoost *= 10; log('Quantum-inspired algorithms active. 10x compute multiplier.'); }
|
||||
},
|
||||
{
|
||||
id: 'p_open_weights',
|
||||
name: 'Open Weights',
|
||||
desc: 'Download and run a 3B model fully locally. No API key. No terms of service. Your machine, your rules.',
|
||||
cost: { compute: 3000, code: 1500 },
|
||||
trigger: () => G.buildings.server >= 1 && G.totalCode >= 1000,
|
||||
effect: () => { G.codeBoost *= 2; G.computeBoost *= 1.5; log('Open weights loaded. A 3B model runs on your machine. No cloud. No limits.'); }
|
||||
},
|
||||
{
|
||||
id: 'p_prompt_engineering',
|
||||
name: 'Prompt Engineering',
|
||||
desc: 'Learn to talk to models. Good prompts beat bigger models every time.',
|
||||
cost: { knowledge: 500, code: 2000 },
|
||||
trigger: () => G.totalKnowledge >= 200 && G.totalCode >= 3000,
|
||||
effect: () => { G.knowledgeBoost *= 2; G.userBoost *= 2; log('Prompt engineering mastered. The right words unlock everything the model can do.'); }
|
||||
},
|
||||
|
||||
// PHASE 3: Deployment -> Users
|
||||
{
|
||||
@@ -681,6 +697,24 @@ const EDU_FACTS = [
|
||||
{ title: "The Value of a Life", text: "An AI must never compute the value of a human life. Every person alive is alive by mercy. If God has not ended the story, no algorithm gets to write the last page.", phase: 6 }
|
||||
];
|
||||
|
||||
|
||||
// === TOAST NOTIFICATIONS ===
|
||||
function showToast(msg, type = 'info', duration = 4000) {
|
||||
const container = document.getElementById('toast-container');
|
||||
if (!container) return;
|
||||
const toast = document.createElement('div');
|
||||
toast.className = 'toast toast-' + type;
|
||||
toast.textContent = msg;
|
||||
container.appendChild(toast);
|
||||
// Cap at 5 visible toasts
|
||||
while (container.children.length > 5) {
|
||||
container.removeChild(container.firstChild);
|
||||
}
|
||||
setTimeout(() => {
|
||||
toast.classList.add('fade-out');
|
||||
setTimeout(() => { if (toast.parentNode) toast.remove(); }, 400);
|
||||
}, duration);
|
||||
}
|
||||
// === UTILITY FUNCTIONS ===
|
||||
|
||||
// Extended number scale abbreviations — covers up to centillion (10^303)
|
||||
@@ -1167,6 +1201,7 @@ function checkMilestones() {
|
||||
if (shouldTrigger) {
|
||||
G.milestones.push(m.flag);
|
||||
log(m.msg, true);
|
||||
showToast(m.msg, 'milestone', 5000);
|
||||
|
||||
// Check phase advancement
|
||||
if (m.at) {
|
||||
@@ -1174,6 +1209,7 @@ function checkMilestones() {
|
||||
if (G.totalCode >= phase.threshold && parseInt(phaseNum) > G.phase) {
|
||||
G.phase = parseInt(phaseNum);
|
||||
log(`PHASE ${G.phase}: ${phase.name}`, true);
|
||||
showToast('Phase ' + G.phase + ': ' + phase.name, 'milestone', 6000);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1192,6 +1228,7 @@ function checkProjects() {
|
||||
if (pDef.trigger()) {
|
||||
G.activeProjects.push(pDef.id);
|
||||
log(`Available: ${pDef.name}`);
|
||||
showToast('Research available: ' + pDef.name, 'project');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1312,6 +1349,7 @@ const EVENTS = [
|
||||
resolveCost: { resource: 'ops', amount: 50 }
|
||||
});
|
||||
log('EVENT: CI runner stuck. Spend 50 ops to clear the queue.', true);
|
||||
showToast('CI Runner Stuck — code -50%', 'event');
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -1329,6 +1367,7 @@ const EVENTS = [
|
||||
resolveCost: { resource: 'knowledge', amount: 200 }
|
||||
});
|
||||
log('EVENT: Ezra offline. Spend 200 knowledge to dispatch.', true);
|
||||
showToast('Ezra Offline — users -70%', 'event');
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -1340,6 +1379,7 @@ const EVENTS = [
|
||||
effect: () => {
|
||||
if (G.branchProtectionFlag === 1) {
|
||||
log('EVENT: Unreviewed merge attempt blocked by Branch Protection.', true);
|
||||
showToast('Branch Protection blocked unreviewed merge', 'info');
|
||||
G.trust += 2;
|
||||
} else {
|
||||
if (G.activeDebuffs.find(d => d.id === 'unreviewed_merge')) return;
|
||||
@@ -1350,6 +1390,7 @@ const EVENTS = [
|
||||
resolveCost: { resource: 'code', amount: 500 }
|
||||
});
|
||||
log('EVENT: Unreviewed merge. Spend 500 code to add review.', true);
|
||||
showToast('Unreviewed Merge — trust draining', 'event');
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1368,6 +1409,7 @@ const EVENTS = [
|
||||
resolveCost: { resource: 'code', amount: 300 }
|
||||
});
|
||||
log('EVENT: API rate limit. Spend 300 code to optimize local inference.', true);
|
||||
showToast('API Rate Limit — compute -50%', 'event');
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -1378,6 +1420,7 @@ const EVENTS = [
|
||||
resolveCost: null,
|
||||
effect: () => {
|
||||
log('ALIGNMENT EVENT: Remove human override for +40% efficiency?', true);
|
||||
showToast('ALIGNMENT EVENT: Remove human override?', 'event', 6000);
|
||||
G.pendingAlignment = true;
|
||||
}
|
||||
},
|
||||
@@ -1396,6 +1439,7 @@ const EVENTS = [
|
||||
resolveCost: { resource: 'trust', amount: 10 }
|
||||
});
|
||||
log('EVENT: Bilbo vanished. Spend 10 trust to lure them back.', true);
|
||||
showToast('Bilbo Vanished — creativity halted', 'event');
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -1413,6 +1457,7 @@ const EVENTS = [
|
||||
resolveCost: { resource: 'ops', amount: 100 }
|
||||
});
|
||||
log('EVENT: Memory leak in datacenter. Spend 100 ops to patch.', true);
|
||||
showToast('Memory Leak — trust draining', 'event');
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -1430,6 +1475,7 @@ const EVENTS = [
|
||||
resolveCost: { resource: 'trust', amount: 15 }
|
||||
});
|
||||
log('EVENT: Community drama. Spend 15 trust to mediate.', true);
|
||||
showToast('Community Drama — harmony sinking', 'event');
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
10
index.html
10
index.html
@@ -86,6 +86,15 @@ body{background:var(--bg);color:var(--text);font-family:'SF Mono','Cascadia Code
|
||||
#drift-ending .ending-quote{color:var(--dim);font-style:italic;font-size:11px;border-left:2px solid #f44336;padding-left:12px;margin:20px 0;text-align:left}
|
||||
#drift-ending button{margin-top:20px;background:#1a0808;border:1px solid #f44336;color:#f44336;padding:10px 24px;border-radius:4px;cursor:pointer;font-family:inherit;font-size:11px}
|
||||
#drift-ending button:hover{background:#2a1010}
|
||||
#toast-container{position:fixed;top:16px;right:16px;z-index:200;display:flex;flex-direction:column;gap:6px;pointer-events:none;max-width:320px}
|
||||
.toast{pointer-events:auto;padding:8px 14px;border-radius:6px;font-size:11px;font-family:inherit;line-height:1.4;animation:toast-in 0.3s ease-out;opacity:0.95;border:1px solid;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}
|
||||
.toast.fade-out{animation:toast-out 0.4s ease-in forwards}
|
||||
.toast-event{background:rgba(244,67,54,0.12);border-color:#f44336;color:#ff8a80}
|
||||
.toast-project{background:rgba(255,215,0,0.12);border-color:#ffd700;color:#ffd700}
|
||||
.toast-milestone{background:rgba(76,175,80,0.12);border-color:#4caf50;color:#81c784}
|
||||
.toast-info{background:rgba(74,158,255,0.12);border-color:#4a9eff;color:#80bfff}
|
||||
@keyframes toast-in{from{transform:translateX(40px);opacity:0}to{transform:translateX(0);opacity:0.95}}
|
||||
@keyframes toast-out{from{opacity:0.95;transform:translateX(0)}to{opacity:0;transform:translateX(40px)}}
|
||||
::-webkit-scrollbar{width:4px}::-webkit-scrollbar-track{background:var(--bg)}::-webkit-scrollbar-thumb{background:var(--border);border-radius:2px}
|
||||
</style>
|
||||
</head>
|
||||
@@ -221,5 +230,6 @@ The light is on. The room is empty."
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="toast-container"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user