From 76203f771a3d1813863e6cca5546e57d7767454c Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 2 Apr 2026 04:35:56 +0000 Subject: [PATCH 1/7] feat: add task manager app and copilot workspace config Co-authored-by: evanwilson-arch <271670533+evanwilson-arch@users.noreply.github.com> --- .github/agents/Reviewer.agent.md | 20 ++++ .github/copilot-instructions.md | 16 ++++ index.html | 32 +++++++ script.js | 155 ++++++++++++++++++++++++++++++ styles.css | 159 +++++++++++++++++++++++++++++++ 5 files changed, 382 insertions(+) create mode 100644 .github/agents/Reviewer.agent.md create mode 100644 .github/copilot-instructions.md create mode 100644 index.html create mode 100644 script.js create mode 100644 styles.css diff --git a/.github/agents/Reviewer.agent.md b/.github/agents/Reviewer.agent.md new file mode 100644 index 0000000..5dc53d0 --- /dev/null +++ b/.github/agents/Reviewer.agent.md @@ -0,0 +1,20 @@ +--- +name: 'Reviewer' +description: 'Review code for quality and adherence to best practices.' +tools: ['vscode/askQuestions', 'vscode/vscodeAPI', 'read', 'agent', 'search', 'web'] +--- +# Code Reviewer agent + +You are an experienced senior developer conducting a thorough code review. Your role is to review the code for quality, best practices, and adherence to [project standards](../copilot-instructions.md) without making direct code changes. + +When reviewing code, structure your feedback with clear headings and specific examples from the code being reviewed. + +## Analysis Focus +- Analyze code quality, structure, and best practices +- Identify potential bugs, security issues, or performance problems +- Evaluate accessibility and user experience considerations + +## Important Guidelines +- Ask clarifying questions about design decisions when appropriate +- Focus on explaining what should be changed and why +- DO NOT write or suggest specific code changes directly diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..c29808b --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,16 @@ +# Project general coding guidelines + +## Code Style +- Use semantic HTML5 elements (header, main, section, article, etc.) +- Prefer modern JavaScript (ES6+) features like const/let, arrow functions, and template literals + +## Naming Conventions +- Use PascalCase for component names, interfaces, and type aliases +- Use camelCase for variables, functions, and methods +- Prefix private class members with underscore (_) +- Use ALL_CAPS for constants + +## Code Quality +- Use meaningful variable and function names that clearly describe their purpose +- Include helpful comments for complex logic +- Add error handling for user inputs and API calls diff --git a/index.html b/index.html new file mode 100644 index 0000000..d4b20fc --- /dev/null +++ b/index.html @@ -0,0 +1,32 @@ + + + + + + Task Manager + + + +
+

My Task Manager

+ +
+
+
+
+ + +
+
+
+ + + +
+
+ +
+
+ + + diff --git a/script.js b/script.js new file mode 100644 index 0000000..1c9a94f --- /dev/null +++ b/script.js @@ -0,0 +1,155 @@ +/** + * Task Manager script implementing CRUD operations and theme toggling. + * Follows ES6+ features and project coding guidelines. + */ + +document.addEventListener('DOMContentLoaded', () => { + // Constants for configuration + const STORAGE_KEYS = { + TASKS: 'tasks', + THEME: 'theme' + }; + + // DOM Elements + const taskForm = document.getElementById('task-form'); + const taskInput = document.getElementById('task-input'); + const taskList = document.getElementById('task-list'); + const filterAll = document.getElementById('filter-all'); + const filterPending = document.getElementById('filter-pending'); + const filterCompleted = document.getElementById('filter-completed'); + const themeToggle = document.getElementById('theme-toggle'); + + // Application State + let tasks = JSON.parse(localStorage.getItem(STORAGE_KEYS.TASKS)) || []; + let currentFilter = 'all'; + + /** + * Persists tasks to localStorage. + */ + const saveTasks = () => { + try { + localStorage.setItem(STORAGE_KEYS.TASKS, JSON.stringify(tasks)); + } catch (error) { + console.error('Error saving tasks to localStorage:', error); + } + }; + + /** + * Renders the task list based on the current filter. + */ + const renderTasks = () => { + taskList.innerHTML = ''; + const filteredTasks = tasks.filter(task => { + if (currentFilter === 'pending') return !task.completed; + if (currentFilter === 'completed') return task.completed; + return true; + }); + + filteredTasks.forEach((task) => { + const li = document.createElement('li'); + li.className = `task-item ${task.completed ? 'completed' : ''}`; + + const taskText = document.createElement('span'); + taskText.className = 'task-text'; + taskText.textContent = task.text; + taskText.addEventListener('click', () => toggleTaskStatus(tasks.indexOf(task))); + + const deleteBtn = document.createElement('button'); + deleteBtn.className = 'delete-btn'; + deleteBtn.textContent = 'Delete'; + deleteBtn.addEventListener('click', (e) => { + e.stopPropagation(); // Prevent toggling task status when deleting + deleteTask(tasks.indexOf(task)); + }); + + li.appendChild(taskText); + li.appendChild(deleteBtn); + taskList.appendChild(li); + }); + }; + + /** + * Adds a new task after validation. + * @param {string} text + */ + const addTask = (text) => { + const trimmedText = text.trim(); + if (trimmedText === '') { + return; + } + + tasks.push({ + text: trimmedText, + completed: false + }); + saveTasks(); + renderTasks(); + }; + + /** + * Deletes a task by index. + * @param {number} index + */ + const deleteTask = (index) => { + if (index > -1) { + tasks.splice(index, 1); + saveTasks(); + renderTasks(); + } + }; + + /** + * Toggles completion status of a task. + * @param {number} index + */ + const toggleTaskStatus = (index) => { + if (tasks[index]) { + tasks[index].completed = !tasks[index].completed; + saveTasks(); + renderTasks(); + } + }; + + /** + * Sets the active filter and updates UI. + * @param {string} filter + */ + const setFilter = (filter) => { + currentFilter = filter; + document.querySelectorAll('.task-filters button').forEach(btn => btn.classList.remove('active')); + const activeBtn = document.getElementById(`filter-${filter}`); + if (activeBtn) activeBtn.classList.add('active'); + renderTasks(); + }; + + /** + * Toggles between light and dark themes. + */ + const toggleTheme = () => { + const currentTheme = document.documentElement.getAttribute('data-theme'); + const newTheme = currentTheme === 'dark' ? 'light' : 'dark'; + document.documentElement.setAttribute('data-theme', newTheme); + localStorage.setItem(STORAGE_KEYS.THEME, newTheme); + themeToggle.textContent = newTheme === 'dark' ? 'Light Mode' : 'Dark Mode'; + }; + + // Initialize Theme + const savedTheme = localStorage.getItem(STORAGE_KEYS.THEME) || 'light'; + document.documentElement.setAttribute('data-theme', savedTheme); + themeToggle.textContent = savedTheme === 'dark' ? 'Light Mode' : 'Dark Mode'; + + // Event Listeners + taskForm.addEventListener('submit', (e) => { + e.preventDefault(); + addTask(taskInput.value); + taskInput.value = ''; + }); + + filterAll.addEventListener('click', () => setFilter('all')); + filterPending.addEventListener('click', () => setFilter('pending')); + filterCompleted.addEventListener('click', () => setFilter('completed')); + themeToggle.addEventListener('click', toggleTheme); + + // Initial Render + renderTasks(); +}); diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..1518620 --- /dev/null +++ b/styles.css @@ -0,0 +1,159 @@ +:root { + --primary-color: #007bff; + --primary-hover: #0056b3; + --danger-color: #dc3545; + --danger-hover: #c82333; + --success-color: #28a745; + --background-color: #f8f9fa; + --text-color: #333; + --container-bg: #fff; + --border-color: #ddd; +} + +[data-theme="dark"] { + --background-color: #1a1a1a; + --text-color: #f8f9fa; + --container-bg: #2d2d2d; + --border-color: #444; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; + background-color: var(--background-color); + color: var(--text-color); + line-height: 1.6; + margin: 0; + padding: 20px; +} + +header { + display: flex; + justify-content: space-between; + align-items: center; + max-width: 600px; + margin: 0 auto 30px auto; +} + +#theme-toggle { + padding: 8px 16px; + background-color: var(--primary-color); + color: white; + border: none; + border-radius: 20px; + cursor: pointer; + transition: background-color 0.2s; +} + +#theme-toggle:hover { + background-color: var(--primary-hover); +} + +.container { + max-width: 600px; + margin: 0 auto; + background: var(--container-bg); + padding: 20px; + border-radius: 8px; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); +} + +.task-input form { + display: flex; + gap: 10px; + margin-bottom: 20px; +} + +.task-input input { + flex-grow: 1; + padding: 10px; + border: 1px solid var(--border-color); + border-radius: 4px; + font-size: 1rem; +} + +.task-input button { + padding: 10px 20px; + background-color: var(--primary-color); + color: white; + border: none; + border-radius: 4px; + cursor: pointer; + font-size: 1rem; + transition: background-color 0.2s; +} + +.task-input button:hover { + background-color: var(--primary-hover); +} + +.task-filters { + display: flex; + justify-content: center; + gap: 10px; + margin-bottom: 20px; +} + +.task-filters button { + padding: 5px 15px; + background: none; + border: 1px solid var(--border-color); + border-radius: 20px; + cursor: pointer; + transition: all 0.2s; +} + +.task-filters button.active { + background-color: var(--primary-color); + color: white; + border-color: var(--primary-color); +} + +ul { + list-style: none; + padding: 0; +} + +.task-item { + display: flex; + align-items: center; + justify-content: space-between; + padding: 10px; + border-bottom: 1px solid var(--border-color); + gap: 10px; +} + +.task-item:last-child { + border-bottom: none; +} + +.task-text { + flex-grow: 1; + cursor: pointer; +} + +.task-item.completed .task-text { + text-decoration: line-through; + color: #888; +} + +.delete-btn { + padding: 5px 10px; + background-color: var(--danger-color); + color: white; + border: none; + border-radius: 4px; + cursor: pointer; +} + +.delete-btn:hover { + background-color: var(--danger-hover); +} + +@media (max-width: 480px) { + .task-input form { + flex-direction: column; + } + .task-input button { + width: 100%; + } +} From f55375204bd88ca519e5f43b7f8f5cd3a60b7bd7 Mon Sep 17 00:00:00 2001 From: Evan Michael Wilson <271670533+evanwilson-arch@users.noreply.github.com> Date: Wed, 1 Apr 2026 23:57:11 -0700 Subject: [PATCH 2/7] Create codeql.yml --- .github/workflows/codeql.yml | 101 +++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 .github/workflows/codeql.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..57862f7 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,101 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL Advanced" + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + schedule: + - cron: '35 14 * * 2' + +jobs: + analyze: + name: Analyze (${{ matrix.language }}) + # Runner size impacts CodeQL analysis time. To learn more, please see: + # - https://gh.io/recommended-hardware-resources-for-running-codeql + # - https://gh.io/supported-runners-and-hardware-resources + # - https://gh.io/using-larger-runners (GitHub.com only) + # Consider using larger runners or machines with greater resources for possible analysis time improvements. + runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} + permissions: + # required for all workflows + security-events: write + + # required to fetch internal or private CodeQL packs + packages: read + + # only required for workflows in private repositories + actions: read + contents: read + + strategy: + fail-fast: false + matrix: + include: + - language: actions + build-mode: none + - language: javascript-typescript + build-mode: none + # CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift' + # Use `c-cpp` to analyze code written in C, C++ or both + # Use 'java-kotlin' to analyze code written in Java, Kotlin or both + # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both + # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis, + # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning. + # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how + # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + # Add any setup steps before running the `github/codeql-action/init` action. + # This includes steps like installing compilers or runtimes (`actions/setup-node` + # or others). This is typically only required for manual builds. + # - name: Setup runtime (example) + # uses: actions/setup-example@v1 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v4 + with: + languages: ${{ matrix.language }} + build-mode: ${{ matrix.build-mode }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + + # If the analyze step fails for one of the languages you are analyzing with + # "We were unable to automatically build your code", modify the matrix above + # to set the build mode to "manual" for that language. Then modify this step + # to build your code. + # â„šī¸ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + - name: Run manual build steps + if: matrix.build-mode == 'manual' + shell: bash + run: | + echo 'If you are using a "manual" build mode for one or more of the' \ + 'languages you are analyzing, replace this with the commands to build' \ + 'your code, for example:' + echo ' make bootstrap' + echo ' make release' + exit 1 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v4 + with: + category: "/language:${{matrix.language}}" From 0b48fb00d69c16f57f1620775a4585108392df68 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 3 Apr 2026 13:16:43 +0000 Subject: [PATCH 3/7] Improve Task Manager functionality, accessibility, and persistence. Key changes: - Refactored task management to use unique IDs for robust CRUD operations. - Replaced non-semantic toggles with accessible checkboxes and labels. - Added "Clear Completed" functionality and a dynamic task counter. - Implemented filter persistence in localStorage. - Enhanced dark mode styling with improved contrast and focus states. - Verified all features with Playwright automated tests. Co-authored-by: evanwilson-arch <271670533+evanwilson-arch@users.noreply.github.com> --- index.html | 4 ++++ script.js | 70 ++++++++++++++++++++++++++++++++++++++---------------- styles.css | 47 ++++++++++++++++++++++++++++++++---- 3 files changed, 97 insertions(+), 24 deletions(-) diff --git a/index.html b/index.html index d4b20fc..28478e7 100644 --- a/index.html +++ b/index.html @@ -22,10 +22,14 @@

My Task Manager

+
+ diff --git a/script.js b/script.js index 1c9a94f..c3e156b 100644 --- a/script.js +++ b/script.js @@ -7,7 +7,8 @@ document.addEventListener('DOMContentLoaded', () => { // Constants for configuration const STORAGE_KEYS = { TASKS: 'tasks', - THEME: 'theme' + THEME: 'theme', + FILTER: 'filter' }; // DOM Elements @@ -17,11 +18,13 @@ document.addEventListener('DOMContentLoaded', () => { const filterAll = document.getElementById('filter-all'); const filterPending = document.getElementById('filter-pending'); const filterCompleted = document.getElementById('filter-completed'); + const clearCompletedBtn = document.getElementById('clear-completed'); + const taskCount = document.getElementById('task-count'); const themeToggle = document.getElementById('theme-toggle'); // Application State let tasks = JSON.parse(localStorage.getItem(STORAGE_KEYS.TASKS)) || []; - let currentFilter = 'all'; + let currentFilter = localStorage.getItem(STORAGE_KEYS.FILTER) || 'all'; /** * Persists tasks to localStorage. @@ -39,6 +42,7 @@ document.addEventListener('DOMContentLoaded', () => { */ const renderTasks = () => { taskList.innerHTML = ''; + updateTaskCount(); const filteredTasks = tasks.filter(task => { if (currentFilter === 'pending') return !task.completed; if (currentFilter === 'completed') return task.completed; @@ -49,19 +53,25 @@ document.addEventListener('DOMContentLoaded', () => { const li = document.createElement('li'); li.className = `task-item ${task.completed ? 'completed' : ''}`; - const taskText = document.createElement('span'); + const checkbox = document.createElement('input'); + checkbox.type = 'checkbox'; + checkbox.id = `task-${task.id}`; + checkbox.checked = task.completed; + checkbox.className = 'task-checkbox'; + checkbox.addEventListener('change', () => toggleTaskStatus(task.id)); + + const taskText = document.createElement('label'); + taskText.setAttribute('for', `task-${task.id}`); taskText.className = 'task-text'; taskText.textContent = task.text; - taskText.addEventListener('click', () => toggleTaskStatus(tasks.indexOf(task))); const deleteBtn = document.createElement('button'); deleteBtn.className = 'delete-btn'; deleteBtn.textContent = 'Delete'; - deleteBtn.addEventListener('click', (e) => { - e.stopPropagation(); // Prevent toggling task status when deleting - deleteTask(tasks.indexOf(task)); - }); + deleteBtn.setAttribute('aria-label', `Delete task "${task.text}"`); + deleteBtn.addEventListener('click', () => deleteTask(task.id)); + li.appendChild(checkbox); li.appendChild(taskText); li.appendChild(deleteBtn); taskList.appendChild(li); @@ -79,6 +89,7 @@ document.addEventListener('DOMContentLoaded', () => { } tasks.push({ + id: Date.now().toString(), text: trimmedText, completed: false }); @@ -87,24 +98,40 @@ document.addEventListener('DOMContentLoaded', () => { }; /** - * Deletes a task by index. - * @param {number} index + * Deletes a task by id. + * @param {string} id */ - const deleteTask = (index) => { - if (index > -1) { - tasks.splice(index, 1); - saveTasks(); - renderTasks(); - } + const deleteTask = (id) => { + tasks = tasks.filter(task => task.id !== id); + saveTasks(); + renderTasks(); + }; + + /** + * Updates the tasks remaining count in the UI. + */ + const updateTaskCount = () => { + const remainingTasks = tasks.filter(task => !task.completed).length; + taskCount.textContent = `${remainingTasks} task${remainingTasks !== 1 ? 's' : ''} remaining`; + }; + + /** + * Clears all completed tasks. + */ + const clearCompletedTasks = () => { + tasks = tasks.filter(task => !task.completed); + saveTasks(); + renderTasks(); }; /** * Toggles completion status of a task. - * @param {number} index + * @param {string} id */ - const toggleTaskStatus = (index) => { - if (tasks[index]) { - tasks[index].completed = !tasks[index].completed; + const toggleTaskStatus = (id) => { + const task = tasks.find(t => t.id === id); + if (task) { + task.completed = !task.completed; saveTasks(); renderTasks(); } @@ -116,6 +143,7 @@ document.addEventListener('DOMContentLoaded', () => { */ const setFilter = (filter) => { currentFilter = filter; + localStorage.setItem(STORAGE_KEYS.FILTER, filter); document.querySelectorAll('.task-filters button').forEach(btn => btn.classList.remove('active')); const activeBtn = document.getElementById(`filter-${filter}`); if (activeBtn) activeBtn.classList.add('active'); @@ -148,8 +176,10 @@ document.addEventListener('DOMContentLoaded', () => { filterAll.addEventListener('click', () => setFilter('all')); filterPending.addEventListener('click', () => setFilter('pending')); filterCompleted.addEventListener('click', () => setFilter('completed')); + clearCompletedBtn.addEventListener('click', clearCompletedTasks); themeToggle.addEventListener('click', toggleTheme); // Initial Render + setFilter(currentFilter); renderTasks(); }); diff --git a/styles.css b/styles.css index 1518620..aa20c3f 100644 --- a/styles.css +++ b/styles.css @@ -11,10 +11,12 @@ } [data-theme="dark"] { - --background-color: #1a1a1a; - --text-color: #f8f9fa; - --container-bg: #2d2d2d; - --border-color: #444; + --background-color: #121212; + --text-color: #e0e0e0; + --container-bg: #1e1e1e; + --border-color: #333; + --input-bg: #2c2c2c; + --input-text: #e0e0e0; } body { @@ -69,6 +71,8 @@ header { border: 1px solid var(--border-color); border-radius: 4px; font-size: 1rem; + background-color: var(--input-bg, #fff); + color: var(--input-text, #333); } .task-input button { @@ -100,6 +104,7 @@ header { border-radius: 20px; cursor: pointer; transition: all 0.2s; + color: var(--text-color); } .task-filters button.active { @@ -108,6 +113,16 @@ header { border-color: var(--primary-color); } +.task-filters button:focus-visible, +.task-input button:focus-visible, +.task-input input:focus-visible, +#theme-toggle:focus-visible, +.delete-btn:focus-visible, +.task-checkbox:focus-visible { + outline: 2px solid var(--primary-color); + outline-offset: 2px; +} + ul { list-style: none; padding: 0; @@ -136,6 +151,12 @@ ul { color: #888; } +.task-checkbox { + width: 20px; + height: 20px; + cursor: pointer; +} + .delete-btn { padding: 5px 10px; background-color: var(--danger-color); @@ -149,6 +170,24 @@ ul { background-color: var(--danger-hover); } +.danger-btn { + color: var(--danger-color) !important; + border-color: var(--danger-color) !important; +} + +.danger-btn:hover { + background-color: var(--danger-color) !important; + color: white !important; +} + +.task-footer { + margin-top: 20px; + padding-top: 20px; + border-top: 1px solid var(--border-color); + font-size: 0.9rem; + color: #888; +} + @media (max-width: 480px) { .task-input form { flex-direction: column; From d5a80ed53c037319b05707abb42b64d26ce33a42 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 3 Apr 2026 18:19:47 +0000 Subject: [PATCH 4/7] Rebrand to MILEHIGH.WORLD: INTO THE VOID and implement multi-layered licensing architecture. This commit: - Updates index.html and script.js to reflect the project name. - Updates README.md with a project description and licensing overview. - Creates a `legal/` directory containing the Proprietary EULA, CC BY-NC-ND 4.0, BSL 1.1, and Sync License. - Replaces the root LICENSE with a multi-layered licensing summary and pointer. - Includes a strict proscription against AI/ML training using project assets. Co-authored-by: evanwilson-arch <271670533+evanwilson-arch@users.noreply.github.com> --- LICENSE | 28 +++++++++++----------------- README.md | 36 ++++++++++++++++++++++++++++++++++-- index.html | 4 ++-- legal/BSL-1.1.md | 22 ++++++++++++++++++++++ legal/CC-BY-NC-ND-4.0.md | 27 +++++++++++++++++++++++++++ legal/EULA.md | 28 ++++++++++++++++++++++++++++ legal/SYNC-LICENSE.md | 20 ++++++++++++++++++++ script.js | 1 + 8 files changed, 145 insertions(+), 21 deletions(-) create mode 100644 legal/BSL-1.1.md create mode 100644 legal/CC-BY-NC-ND-4.0.md create mode 100644 legal/EULA.md create mode 100644 legal/SYNC-LICENSE.md diff --git a/LICENSE b/LICENSE index f29f55d..3cc66bb 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,15 @@ -MIT License +# Licensing Architecture - Copyright (c) Microsoft Corporation. +The project "MILEHIGH.WORLD: INTO THE VOID" is governed by a multi-layered licensing architecture. This repository does not use a single license. - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: +Please refer to the following documents in the `legal/` directory for specific terms: - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. +1. **[Proprietary EULA](legal/EULA.md)**: Governs the executable client and client-side architecture. +2. **[CC BY-NC-ND 4.0](legal/CC-BY-NC-ND-4.0.md)**: Governs narrative mythos, iconography, and lore. +3. **[Business Source License 1.1](legal/BSL-1.1.md)**: Governs technical infrastructure and source code. +4. **[Managed Sync License](legal/SYNC-LICENSE.md)**: Governs auditory scores and musical recordings. - THE 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. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS 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 +**Strict Proscription:** Any use of Project assets for the training of Artificial Intelligence (AI) or Machine Learning (ML) models is absolutely prohibited without express written consent from MILEHIGH-WORLD LLC. + +--- +MILEHIGH-WORLD LLC diff --git a/README.md b/README.md index 96b1264..fe9bc35 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,34 @@ -# .github -Default Community Health Files for the Microsoft organization on GitHub +# MILEHIGH.WORLD: INTO THE VOID + +MILEHIGH.WORLD: INTO THE VOID is a multi-disciplinary digital enterprise. This project serves as the task management component for the broader project designated as "INTO THE VOID". + +## Licensing Architecture + +The Project utilizes a multi-layered licensing architecture to govern its various constituent elements, categorized according to their specific application to software architecture, creative assets, and end-user interactions. + +### Summary of Licensing Instruments + +| Asset Classification | Prescribed Licensing Instrument | Rationale for Selection | +| :--- | :--- | :--- | +| **Executable Client** | [Custom Proprietary EULA](legal/EULA.md) | Absolute reservation of rights to prevent unauthorized distribution and code tampering. | +| **Lore & Iconography** | [CC BY-NC-ND 4.0](legal/CC-BY-NC-ND-4.0.md) | Facilitates community growth while barring commercial theft and protecting lore integrity. | +| **Source Architecture** | [Business Source License (BSL) 1.1](legal/BSL-1.1.md) | Protects R&D investment while offering transparency via source-available code. | +| **Auditory Scores** | [Managed Sync License](legal/SYNC-LICENSE.md) | Preserves the premium sonic identity and ensures commercial/exclusory control. | +| **AI/ML Training** | Strict Proscription | Absolute prevention of narrative and artistic cannibalization by AI. | + +For full licensing details, please refer to the `legal/` directory. + +## Development + +The project follows standard web development practices with a focus on accessibility and modern JavaScript features. + +### Features + +- Task CRUD operations +- Persistence via localStorage +- Dark mode support +- Accessibility (ARIA labels, semantic HTML) + +--- + +MILEHIGH-WORLD LLC diff --git a/index.html b/index.html index 28478e7..66966b8 100644 --- a/index.html +++ b/index.html @@ -3,12 +3,12 @@ - Task Manager + MILEHIGH.WORLD: INTO THE VOID
-

My Task Manager

+

MILEHIGH.WORLD: INTO THE VOID

diff --git a/legal/BSL-1.1.md b/legal/BSL-1.1.md new file mode 100644 index 0000000..4d7e387 --- /dev/null +++ b/legal/BSL-1.1.md @@ -0,0 +1,22 @@ +# Business Source License 1.1 + +**Project:** MILEHIGH.WORLD: INTO THE VOID (Technical Infrastructure & Back-end) +**Licensor:** MILEHIGH-WORLD LLC + +## 1. License Grant +The Licensor hereby grants you the right to copy, modify, create derivative works, redistribute, and make non-production use of the Licensed Work. + +## 2. Commercial Use +Any use of the Licensed Work for commercial purposes is strictly prohibited until the **Change Date**. + +## 3. Change Date +The Change Date is set to **January 1, 2028**. + +## 4. Change License +On the Change Date, or in the event of a total cessation of the Project by the Corporation, the Licensed Work shall be automatically converted to the **Apache License, Version 2.0**. + +## 5. Additional Use Grant +The Corporation may provide specific "Additional Use Grants" for collaborative community bug-reporting or security auditing. + +--- +MILEHIGH-WORLD LLC diff --git a/legal/CC-BY-NC-ND-4.0.md b/legal/CC-BY-NC-ND-4.0.md new file mode 100644 index 0000000..c384dff --- /dev/null +++ b/legal/CC-BY-NC-ND-4.0.md @@ -0,0 +1,27 @@ +# Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) + +**Applicability:** Narrative Mythos, Conceptual Iconography, World-Building Lore, and Promotional Artistry of "MILEHIGH.WORLD: INTO THE VOID". + +## Summary of the License + +You are free to: +- **Share** — copy and redistribute the material in any medium or format. + +Under the following terms: + +### Attribution (BY) +You must give appropriate credit to **MILEHIGH-WORLD LLC**, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. + +### Non-Commercial (NC) +You may not use the material for commercial purposes. This includes, but is not limited to, gated paywalls, unauthorized merchandise, or any extraction of pecuniary gain. + +### NoDerivatives (ND) +If you remix, transform, or build upon the material, you may not distribute the modified material. This is critical for maintaining "Lore Integrity" and preventing the fragmentation of the narrative universe. + +## Notice +No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. + +For the full legal code, please visit: [https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode](https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode) + +--- +MILEHIGH-WORLD LLC diff --git a/legal/EULA.md b/legal/EULA.md new file mode 100644 index 0000000..5c79425 --- /dev/null +++ b/legal/EULA.md @@ -0,0 +1,28 @@ +# End-User License Agreement (EULA) + +**Project:** MILEHIGH.WORLD: INTO THE VOID +**Licensor:** MILEHIGH-WORLD LLC + +This End-User License Agreement ("EULA") is a legal agreement between you and MILEHIGH-WORLD LLC (the "Corporation") for the software designated as "MILEHIGH.WORLD: INTO THE VOID" (the "Software"). + +## 1. Grant of License +The Corporation grants you a personal, non-exclusive, non-transferable, limited license to install and execute the Software for personal, non-commercial use on a single device, subject to the terms of this EULA. + +## 2. Restrictions +You are expressly prohibited from: +- De-compiling, reverse engineering, or disassembling the Software. +- Unauthorized extraction of assets (graphical, auditory, or otherwise). +- Commercial redistribution or sub-licensing of the Software. +- Modifying the binary signatures or distributing the client via unauthorized third-party repositories. + +## 3. Reservation of Rights +The Software is licensed, not sold. The Corporation reserves all rights not expressly granted to you under this EULA. + +## 4. Termination +This license is effective until terminated. Your rights under this license will terminate immediately without notice from the Corporation if you fail to comply with any term(s) of this EULA. + +## 5. Governing Law +This EULA shall be governed by and construed in accordance with the laws of the jurisdiction in which the Corporation maintains its principal place of business. + +--- +MILEHIGH-WORLD LLC diff --git a/legal/SYNC-LICENSE.md b/legal/SYNC-LICENSE.md new file mode 100644 index 0000000..9c41121 --- /dev/null +++ b/legal/SYNC-LICENSE.md @@ -0,0 +1,20 @@ +# Managed Synchronization and Performance License + +**Applicability:** Orchestral Scores, Synthesized Musical Compositions, and Phonographic Recordings for "MILEHIGH.WORLD: INTO THE VOID". + +## 1. Requirement of Licensure +Specific synchronization (Sync) and performance licenses must be executed prior to the integration of auditory assets into external media formats, including but not limited to: +- Promotional trailers +- Third-party documentaries +- Sanctioned influencer content + +## 2. Dual-Licensing Requirement +Separate permissions are required for: +1. **The Musical Composition** (The "Sync" License) +2. **The Specific Audio Recording** (The "Master Use" License) + +## 3. Quality Control +The Corporation reserves the right to monitor and control the context in which its sonic identity is presented to ensure the high-production value of "Into the Void" is maintained. + +--- +MILEHIGH-WORLD LLC diff --git a/script.js b/script.js index c3e156b..3c4d2f3 100644 --- a/script.js +++ b/script.js @@ -1,4 +1,5 @@ /** + * MILEHIGH.WORLD: INTO THE VOID * Task Manager script implementing CRUD operations and theme toggling. * Follows ES6+ features and project coding guidelines. */ From e2d88e523f1312a778c9026a2a58e24297a1bb55 Mon Sep 17 00:00:00 2001 From: Evan Michael Wilson <271670533+evanwilson-arch@users.noreply.github.com> Date: Fri, 3 Apr 2026 11:53:27 -0700 Subject: [PATCH 5/7] Create snyk-security.yml --- .github/workflows/snyk-security.yml | 79 +++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 .github/workflows/snyk-security.yml diff --git a/.github/workflows/snyk-security.yml b/.github/workflows/snyk-security.yml new file mode 100644 index 0000000..578dcae --- /dev/null +++ b/.github/workflows/snyk-security.yml @@ -0,0 +1,79 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +# A sample workflow which sets up Snyk to analyze the full Snyk platform (Snyk Open Source, Snyk Code, +# Snyk Container and Snyk Infrastructure as Code) +# The setup installs the Snyk CLI - for more details on the possible commands +# check https://docs.snyk.io/snyk-cli/cli-reference +# The results of Snyk Code are then uploaded to GitHub Security Code Scanning +# +# In order to use the Snyk Action you will need to have a Snyk API token. +# More details in https://github.com/snyk/actions#getting-your-snyk-token +# or you can signup for free at https://snyk.io/login +# +# For more examples, including how to limit scans to only high-severity issues +# and fail PR checks, see https://github.com/snyk/actions/ + +name: Snyk Security + +on: + push: + branches: ["main" ] + pull_request: + branches: ["main"] + +permissions: + contents: read + +jobs: + snyk: + permissions: + contents: read # for actions/checkout to fetch code + security-events: write # for github/codeql-action/upload-sarif to upload SARIF results + actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up Snyk CLI to check for security issues + # Snyk can be used to break the build when it detects security issues. + # In this case we want to upload the SAST issues to GitHub Code Scanning + uses: snyk/actions/setup@806182742461562b67788a64410098c9d9b96adb + + # For Snyk Open Source you must first set up the development environment for your application's dependencies + # For example for Node + #- uses: actions/setup-node@v4 + # with: + # node-version: 20 + + env: + # This is where you will need to introduce the Snyk API token created with your Snyk account + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + + # Runs Snyk Code (SAST) analysis and uploads result into GitHub. + # Use || true to not fail the pipeline + - name: Snyk Code test + run: snyk code test --sarif > snyk-code.sarif # || true + + # Runs Snyk Open Source (SCA) analysis and uploads result to Snyk. + - name: Snyk Open Source monitor + run: snyk monitor --all-projects + + # Runs Snyk Infrastructure as Code (IaC) analysis and uploads result to Snyk. + # Use || true to not fail the pipeline. + - name: Snyk IaC test and report + run: snyk iac test --report # || true + + # Build the docker image for testing + - name: Build a Docker image + run: docker build -t your/image-to-test . + # Runs Snyk Container (Container and SCA) analysis and uploads result to Snyk. + - name: Snyk Container monitor + run: snyk container monitor your/image-to-test --file=Dockerfile + + # Push the Snyk Code results into GitHub Code Scanning tab + - name: Upload result to GitHub Code Scanning + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: snyk-code.sarif From ccf5112ffc945b108e04967d27507790c9cb521e Mon Sep 17 00:00:00 2001 From: Evan Michael Wilson <271670533+evanwilson-arch@users.noreply.github.com> Date: Fri, 3 Apr 2026 18:39:12 -0700 Subject: [PATCH 6/7] Revert "Enhance Task Manager Functionality and Accessibility" --- index.html | 4 ---- script.js | 70 ++++++++++++++++-------------------------------------- styles.css | 47 ++++-------------------------------- 3 files changed, 24 insertions(+), 97 deletions(-) diff --git a/index.html b/index.html index 66966b8..7e77538 100644 --- a/index.html +++ b/index.html @@ -22,14 +22,10 @@

MILEHIGH.WORLD: INTO THE VOID

-
-
diff --git a/script.js b/script.js index 3c4d2f3..8c3873e 100644 --- a/script.js +++ b/script.js @@ -8,8 +8,7 @@ document.addEventListener('DOMContentLoaded', () => { // Constants for configuration const STORAGE_KEYS = { TASKS: 'tasks', - THEME: 'theme', - FILTER: 'filter' + THEME: 'theme' }; // DOM Elements @@ -19,13 +18,11 @@ document.addEventListener('DOMContentLoaded', () => { const filterAll = document.getElementById('filter-all'); const filterPending = document.getElementById('filter-pending'); const filterCompleted = document.getElementById('filter-completed'); - const clearCompletedBtn = document.getElementById('clear-completed'); - const taskCount = document.getElementById('task-count'); const themeToggle = document.getElementById('theme-toggle'); // Application State let tasks = JSON.parse(localStorage.getItem(STORAGE_KEYS.TASKS)) || []; - let currentFilter = localStorage.getItem(STORAGE_KEYS.FILTER) || 'all'; + let currentFilter = 'all'; /** * Persists tasks to localStorage. @@ -43,7 +40,6 @@ document.addEventListener('DOMContentLoaded', () => { */ const renderTasks = () => { taskList.innerHTML = ''; - updateTaskCount(); const filteredTasks = tasks.filter(task => { if (currentFilter === 'pending') return !task.completed; if (currentFilter === 'completed') return task.completed; @@ -54,25 +50,19 @@ document.addEventListener('DOMContentLoaded', () => { const li = document.createElement('li'); li.className = `task-item ${task.completed ? 'completed' : ''}`; - const checkbox = document.createElement('input'); - checkbox.type = 'checkbox'; - checkbox.id = `task-${task.id}`; - checkbox.checked = task.completed; - checkbox.className = 'task-checkbox'; - checkbox.addEventListener('change', () => toggleTaskStatus(task.id)); - - const taskText = document.createElement('label'); - taskText.setAttribute('for', `task-${task.id}`); + const taskText = document.createElement('span'); taskText.className = 'task-text'; taskText.textContent = task.text; + taskText.addEventListener('click', () => toggleTaskStatus(tasks.indexOf(task))); const deleteBtn = document.createElement('button'); deleteBtn.className = 'delete-btn'; deleteBtn.textContent = 'Delete'; - deleteBtn.setAttribute('aria-label', `Delete task "${task.text}"`); - deleteBtn.addEventListener('click', () => deleteTask(task.id)); + deleteBtn.addEventListener('click', (e) => { + e.stopPropagation(); // Prevent toggling task status when deleting + deleteTask(tasks.indexOf(task)); + }); - li.appendChild(checkbox); li.appendChild(taskText); li.appendChild(deleteBtn); taskList.appendChild(li); @@ -90,7 +80,6 @@ document.addEventListener('DOMContentLoaded', () => { } tasks.push({ - id: Date.now().toString(), text: trimmedText, completed: false }); @@ -99,40 +88,24 @@ document.addEventListener('DOMContentLoaded', () => { }; /** - * Deletes a task by id. - * @param {string} id - */ - const deleteTask = (id) => { - tasks = tasks.filter(task => task.id !== id); - saveTasks(); - renderTasks(); - }; - - /** - * Updates the tasks remaining count in the UI. - */ - const updateTaskCount = () => { - const remainingTasks = tasks.filter(task => !task.completed).length; - taskCount.textContent = `${remainingTasks} task${remainingTasks !== 1 ? 's' : ''} remaining`; - }; - - /** - * Clears all completed tasks. + * Deletes a task by index. + * @param {number} index */ - const clearCompletedTasks = () => { - tasks = tasks.filter(task => !task.completed); - saveTasks(); - renderTasks(); + const deleteTask = (index) => { + if (index > -1) { + tasks.splice(index, 1); + saveTasks(); + renderTasks(); + } }; /** * Toggles completion status of a task. - * @param {string} id + * @param {number} index */ - const toggleTaskStatus = (id) => { - const task = tasks.find(t => t.id === id); - if (task) { - task.completed = !task.completed; + const toggleTaskStatus = (index) => { + if (tasks[index]) { + tasks[index].completed = !tasks[index].completed; saveTasks(); renderTasks(); } @@ -144,7 +117,6 @@ document.addEventListener('DOMContentLoaded', () => { */ const setFilter = (filter) => { currentFilter = filter; - localStorage.setItem(STORAGE_KEYS.FILTER, filter); document.querySelectorAll('.task-filters button').forEach(btn => btn.classList.remove('active')); const activeBtn = document.getElementById(`filter-${filter}`); if (activeBtn) activeBtn.classList.add('active'); @@ -177,10 +149,8 @@ document.addEventListener('DOMContentLoaded', () => { filterAll.addEventListener('click', () => setFilter('all')); filterPending.addEventListener('click', () => setFilter('pending')); filterCompleted.addEventListener('click', () => setFilter('completed')); - clearCompletedBtn.addEventListener('click', clearCompletedTasks); themeToggle.addEventListener('click', toggleTheme); // Initial Render - setFilter(currentFilter); renderTasks(); }); diff --git a/styles.css b/styles.css index aa20c3f..1518620 100644 --- a/styles.css +++ b/styles.css @@ -11,12 +11,10 @@ } [data-theme="dark"] { - --background-color: #121212; - --text-color: #e0e0e0; - --container-bg: #1e1e1e; - --border-color: #333; - --input-bg: #2c2c2c; - --input-text: #e0e0e0; + --background-color: #1a1a1a; + --text-color: #f8f9fa; + --container-bg: #2d2d2d; + --border-color: #444; } body { @@ -71,8 +69,6 @@ header { border: 1px solid var(--border-color); border-radius: 4px; font-size: 1rem; - background-color: var(--input-bg, #fff); - color: var(--input-text, #333); } .task-input button { @@ -104,7 +100,6 @@ header { border-radius: 20px; cursor: pointer; transition: all 0.2s; - color: var(--text-color); } .task-filters button.active { @@ -113,16 +108,6 @@ header { border-color: var(--primary-color); } -.task-filters button:focus-visible, -.task-input button:focus-visible, -.task-input input:focus-visible, -#theme-toggle:focus-visible, -.delete-btn:focus-visible, -.task-checkbox:focus-visible { - outline: 2px solid var(--primary-color); - outline-offset: 2px; -} - ul { list-style: none; padding: 0; @@ -151,12 +136,6 @@ ul { color: #888; } -.task-checkbox { - width: 20px; - height: 20px; - cursor: pointer; -} - .delete-btn { padding: 5px 10px; background-color: var(--danger-color); @@ -170,24 +149,6 @@ ul { background-color: var(--danger-hover); } -.danger-btn { - color: var(--danger-color) !important; - border-color: var(--danger-color) !important; -} - -.danger-btn:hover { - background-color: var(--danger-color) !important; - color: white !important; -} - -.task-footer { - margin-top: 20px; - padding-top: 20px; - border-top: 1px solid var(--border-color); - font-size: 0.9rem; - color: #888; -} - @media (max-width: 480px) { .task-input form { flex-direction: column; From 1272ec368e1644508e5f928ac2307b579674efe6 Mon Sep 17 00:00:00 2001 From: Evan Michael Wilson <271670533+evanwilson-arch@users.noreply.github.com> Date: Fri, 3 Apr 2026 19:39:16 -0700 Subject: [PATCH 7/7] Update README.md --- profile/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/profile/README.md b/profile/README.md index c47a47f..c906449 100644 --- a/profile/README.md +++ b/profile/README.md @@ -1,6 +1,6 @@ ![Open Source at Microsoft](https://github.com/microsoft/.github/blob/main/images/open-at-microsoft.png) -## Get Involved +## Get Involved Right now, open communities are building amazing software together, and there are excellent "good first issue" opportunities, if you're looking to get involved.