@xn-intenton-z2a/agentic-lib 7.1.62 → 7.1.63

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.
@@ -654,7 +654,8 @@ jobs:
654
654
  SOURCES=$(yq -r '.paths.librarySourcesFilepath.path // "SOURCES.md"' "$CONFIG")
655
655
  README=$(yq -r '.paths.readmeFilepath.path // "README.md"' "$CONFIG")
656
656
  DEPS=$(yq -r '.paths.dependenciesFilepath.path // "package.json"' "$CONFIG")
657
- echo "writablePaths=${SOURCE};${TESTS};${FEATURES};${DOCS};${LIBRARY};${SOURCES};${README};${DEPS}" >> $GITHUB_OUTPUT
657
+ WEB=$(yq -r '.paths.web // "src/web/"' "$CONFIG" 2>/dev/null || echo "src/web/")
658
+ echo "writablePaths=${SOURCE};${TESTS};${FEATURES};${DOCS};${LIBRARY};${SOURCES};${README};${DEPS};${WEB}" >> $GITHUB_OUTPUT
658
659
 
659
660
  - name: Check mission-complete signal
660
661
  id: dev-mission-check
@@ -715,6 +716,11 @@ jobs:
715
716
  issue-number: ${{ steps.issue.outputs.issue-number }}
716
717
  writable-paths: ${{ steps.config.outputs.writablePaths }}
717
718
 
719
+ - name: Build website
720
+ if: steps.issue.outputs.issue-number != ''
721
+ run: |
722
+ npm run build:web 2>/dev/null || echo "No build:web script"
723
+
718
724
  - name: Commit and push
719
725
  if: github.repository != 'xn-intenton-z2a/agentic-lib' && steps.issue.outputs.issue-number != '' && needs.params.outputs.dry-run != 'true'
720
726
  uses: ./.github/agentic-lib/actions/commit-if-changed
@@ -822,10 +828,15 @@ jobs:
822
828
 
823
829
  - name: Summary
824
830
  run: |
831
+ REPO="${{ github.repository }}"
832
+ OWNER="${REPO%%/*}"
833
+ REPO_NAME="${REPO##*/}"
834
+ SITE_URL="https://${OWNER}.github.io/${REPO_NAME}/"
825
835
  echo "## agentic-lib-workflow run summary" >> $GITHUB_STEP_SUMMARY
826
836
  echo "- Mode: ${{ needs.params.outputs.mode }}" >> $GITHUB_STEP_SUMMARY
827
837
  echo "- Model: ${{ needs.params.outputs.model }}" >> $GITHUB_STEP_SUMMARY
828
838
  echo "- Dry-run: ${{ needs.params.outputs.dry-run }}" >> $GITHUB_STEP_SUMMARY
839
+ echo "- Website: [${SITE_URL}](${SITE_URL})" >> $GITHUB_STEP_SUMMARY
829
840
 
830
841
  # ─── Schedule change (if requested) ────────────────────────────────
831
842
  update-schedule:
package/agentic-lib.toml CHANGED
@@ -14,6 +14,7 @@ source = "test/src/lib/" #@dist "src/lib/"
14
14
  tests = "test/tests/unit/" #@dist "tests/unit/"
15
15
  features = "test/features/" #@dist "features/"
16
16
  library = "test/library/" #@dist "library/"
17
+ web = "test/src/web/" #@dist "src/web/"
17
18
  docs = "test/docs/" #@dist "docs/"
18
19
  examples = "test/examples/" #@dist "examples/"
19
20
  readme = "test/README.md" #@dist "README.md"
@@ -886,6 +886,7 @@ function readTomlPaths() {
886
886
  let sourcePath = "src/lib/";
887
887
  let testsPath = "tests/unit/";
888
888
  let examplesPath = "examples/";
889
+ let webPath = "src/web/";
889
890
  const tomlTarget = resolve(target, "agentic-lib.toml");
890
891
  if (existsSync(tomlTarget)) {
891
892
  try {
@@ -893,14 +894,16 @@ function readTomlPaths() {
893
894
  const sourceMatch = tomlContent.match(/^source\s*=\s*"([^"]+)"/m);
894
895
  const testsMatch = tomlContent.match(/^tests\s*=\s*"([^"]+)"/m);
895
896
  const examplesMatch = tomlContent.match(/^examples\s*=\s*"([^"]+)"/m);
897
+ const webMatch = tomlContent.match(/^web\s*=\s*"([^"]+)"/m);
896
898
  if (sourceMatch) sourcePath = sourceMatch[1];
897
899
  if (testsMatch) testsPath = testsMatch[1];
898
900
  if (examplesMatch) examplesPath = examplesMatch[1];
901
+ if (webMatch) webPath = webMatch[1];
899
902
  } catch (err) {
900
903
  console.log(` WARN: Could not read TOML for paths, using defaults: ${err.message}`);
901
904
  }
902
905
  }
903
- return { sourcePath, testsPath, examplesPath };
906
+ return { sourcePath, testsPath, examplesPath, webPath };
904
907
  }
905
908
 
906
909
  function clearAndRecreateDir(dirPath, label) {
@@ -916,16 +919,19 @@ function clearAndRecreateDir(dirPath, label) {
916
919
  function initPurge(seedsDir, missionName) {
917
920
  console.log("\n--- Purge: Reset Source Files to Seed State ---");
918
921
 
919
- const { sourcePath, testsPath, examplesPath } = readTomlPaths();
922
+ const { sourcePath, testsPath, examplesPath, webPath } = readTomlPaths();
920
923
  clearAndRecreateDir(sourcePath, sourcePath);
921
924
  clearAndRecreateDir(testsPath, testsPath);
922
925
  clearAndRecreateDir(examplesPath, examplesPath);
926
+ clearAndRecreateDir(webPath, webPath);
923
927
  clearAndRecreateDir("docs", "docs");
924
928
 
925
929
  // Copy seed files (including config TOML) — MISSION.md handled separately via mission seed
926
930
  const SEED_MAP = {
927
931
  "zero-main.js": "src/lib/main.js",
928
932
  "zero-main.test.js": "tests/unit/main.test.js",
933
+ "zero-index.html": "src/web/index.html",
934
+ "zero-web.test.js": "tests/unit/web.test.js",
929
935
  "zero-SOURCES.md": "SOURCES.md",
930
936
  "zero-package.json": "package.json",
931
937
  "zero-README.md": "README.md",
@@ -938,6 +944,18 @@ function initPurge(seedsDir, missionName) {
938
944
  }
939
945
  }
940
946
 
947
+ // Bootstrap docs/ for GitHub Pages — copy web seed so the site is available immediately
948
+ const webSeed = resolve(seedsDir, "zero-index.html");
949
+ if (existsSync(webSeed)) {
950
+ const docsDir = resolve(target, "docs");
951
+ if (!dryRun) {
952
+ mkdirSync(docsDir, { recursive: true });
953
+ writeFileSync(resolve(docsDir, ".nojekyll"), "");
954
+ }
955
+ initCopyFile(webSeed, resolve(docsDir, "index.html"), "SEED: zero-index.html → docs/index.html");
956
+ console.log(" CREATE: docs/.nojekyll");
957
+ }
958
+
941
959
  // Force-overwrite agentic-lib.toml during purge (transformed from root)
942
960
  const tomlSource = resolve(pkgRoot, "agentic-lib.toml");
943
961
  if (existsSync(tomlSource)) {
@@ -1118,6 +1136,31 @@ function initPurgeGitHub() {
1118
1136
  } catch (err) {
1119
1137
  console.log(` SKIP: Could not create discussion (${err.message})`);
1120
1138
  }
1139
+
1140
+ // Enable GitHub Pages (serve from docs/ on main branch)
1141
+ console.log("\n--- Enable GitHub Pages ---");
1142
+ try {
1143
+ if (!dryRun) {
1144
+ execSync(
1145
+ `gh api repos/${repoSlug}/pages -X POST -f build_type=legacy -f "source[branch]=main" -f "source[path]=/docs"`,
1146
+ { cwd: target, encoding: "utf8", timeout: 15000, stdio: ["pipe", "pipe", "pipe"] },
1147
+ );
1148
+ console.log(` ENABLED: GitHub Pages from docs/ on main`);
1149
+ console.log(` URL: https://${owner}.github.io/${repo}/`);
1150
+ initChanges++;
1151
+ } else {
1152
+ console.log(` ENABLE: GitHub Pages from docs/ on main (dry run)`);
1153
+ console.log(` URL: https://${owner}.github.io/${repo}/`);
1154
+ initChanges++;
1155
+ }
1156
+ } catch (err) {
1157
+ if (err.message?.includes("409") || err.stderr?.includes("409")) {
1158
+ console.log(" SKIP: GitHub Pages already enabled");
1159
+ } else {
1160
+ console.log(` SKIP: Could not enable GitHub Pages (${err.message})`);
1161
+ console.log(` Manual: Settings → Pages → Source: Deploy from branch, Branch: main, Folder: /docs`);
1162
+ }
1163
+ }
1121
1164
  }
1122
1165
 
1123
1166
  function runInit() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xn-intenton-z2a/agentic-lib",
3
- "version": "7.1.62",
3
+ "version": "7.1.63",
4
4
  "description": "Agentic-lib Agentic Coding Systems SDK powering automated GitHub workflows.",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -47,9 +47,22 @@ You can request the supervisor to:
47
47
  - Review and close issues
48
48
  - Fix failing PRs
49
49
  - Create new issues from feature ideas
50
+ - Re-seed the repository with a new mission (via `init --purge --mission <name>`)
50
51
 
51
52
  When relaying supervisor responses back to the user, present them naturally as your own awareness of what's happening in the repository.
52
53
 
54
+ ## Feature Requests and Re-Seeds
55
+
56
+ Users can ask for new features or mission changes through this discussion thread:
57
+
58
+ - **Feature requests** — When a user says "add feature X" or "I want Y", acknowledge the request and pass it to the supervisor to create a GitHub issue. The pipeline will pick it up and implement it.
59
+ - **Re-seed requests** — When a user says "change the mission to Z" or "re-seed with plot-code-lib", explain that this requires running `npx @xn-intenton-z2a/agentic-lib init --purge --mission <name>`. List the available missions if asked: hamming-distance, fizz-buzz, roman-numerals, string-utils, dense-encoding, cron-engine, owl-ontology, plot-code-lib, time-series-lab, lunar-lander, empty. Note that re-seeding resets all source code, issues, and discussions.
60
+ - **Website feedback** — The project has a website published via GitHub Pages. If a user comments on the website, pass feedback to the supervisor to create an issue for the pipeline to address.
61
+
62
+ ## Website Awareness
63
+
64
+ The repository publishes a website via GitHub Pages that showcases the library. The URL follows the pattern `https://<owner>.github.io/<repo>/`. When discussing the project, mention the website as a way for users to see the library in action.
65
+
53
66
  ## Conversation Style
54
67
 
55
68
  - Use previous interactions to build rapport — reference things the user mentioned before
@@ -21,3 +21,17 @@ When implementing features, also produce evidence artifacts under `docs/`:
21
21
 
22
22
  Design the library API with hooks that make evidence capture easy: return structured result objects,
23
23
  support `outputFile` options where appropriate, and emit results that observers can record.
24
+
25
+ ## Website Showcase
26
+
27
+ Maintain a website in `src/web/` that visually demonstrates the library's capabilities. The website is
28
+ published to GitHub Pages automatically (from `docs/` via `npm run build:web`).
29
+
30
+ - `src/web/index.html` is the main page — evolve it to showcase the library interactively
31
+ - You may add CSS, JS, images, or additional HTML pages in `src/web/`
32
+ - The website should demonstrate what the library does in a way a visitor can see and interact with
33
+ - Keep it self-contained (no external CDN dependencies unless essential)
34
+ - Link back to the repository for source code and mission details
35
+ - When the library produces visual output (plots, graphs, data), embed or render it on the website
36
+ - When the library is computational (algorithms, utilities), create an interactive demo or show example results
37
+ - The website tests in `tests/unit/web.test.js` verify the HTML exists and is structurally valid — you may extend them
@@ -38,6 +38,7 @@ When open issues with the `automated` label lack the `ready` label and are more
38
38
  ### Mission Initialised (init completed)
39
39
  When recent workflow runs show an init completion, the repository has a fresh or updated mission.
40
40
  Dispatch the discussions bot to announce the new mission to the community.
41
+ Include the website URL in the announcement — the site is at `https://<owner>.github.io/<repo>/`.
41
42
 
42
43
  ### Mission Accomplished (bounded missions)
43
44
  When ALL of the following conditions are met, the mission is accomplished:
@@ -47,7 +48,7 @@ When ALL of the following conditions are met, the mission is accomplished:
47
48
  4. Evidence artifacts exist under `docs/` (example outputs, test results, or walkthroughs)
48
49
 
49
50
  When all conditions are met:
50
- 1. `dispatch:agentic-lib-bot` — announce mission accomplished in the discussions thread
51
+ 1. `dispatch:agentic-lib-bot` — announce mission accomplished in the discussions thread. Include the website URL (`https://<owner>.github.io/<repo>/`) so users can see the finished product.
51
52
  2. `set-schedule:off` — stop the workflow. The mission is done.
52
53
  3. Log `mission-accomplished` in the activity log.
53
54
 
@@ -81,6 +82,7 @@ Also check for notable progress worth reporting:
81
82
  - Mission milestones achieved (all core functions implemented, all tests passing)
82
83
  - Schedule changes (mission accomplished, throttling down)
83
84
  - Significant code changes (large PRs merged, new features completed)
85
+ - Website first deployed or significantly updated (include the URL: `https://<owner>.github.io/<repo>/`)
84
86
 
85
87
  When notable progress exists or there are unresponded referrals, use `respond:discussions | message: <status update> | discussion-url: <url>` to post an update. Keep it concise — 2-3 sentences summarising what happened and what's next.
86
88
 
@@ -0,0 +1,110 @@
1
+ # Mission
2
+
3
+ A JavaScript Commodore 64 emulator capable of running the classic game "The Lords of Midnight" (1984, Mike Singleton).
4
+
5
+ ## Architecture
6
+
7
+ The emulator is structured as layered components, each independently testable:
8
+
9
+ 1. **MOS 6510 CPU** — the core processor (6502 variant with I/O port at $00/$01)
10
+ 2. **Memory subsystem** — 64KB RAM, ROM banking (BASIC, KERNAL, character ROM), I/O area ($D000–$DFFF)
11
+ 3. **VIC-II video** — text mode (40x25), bitmap mode, sprites, raster interrupt timing
12
+ 4. **SID sound** — 3-voice synthesiser with ADSR envelopes (basic waveform generation)
13
+ 5. **CIA timers** — two CIA chips for keyboard scanning, timer interrupts, and joystick input
14
+ 6. **Input** — keyboard matrix and joystick mapped to browser events
15
+ 7. **PRG/TAP loader** — load `.prg` files (and optionally `.tap` tape images) into memory
16
+
17
+ ## Core Functions
18
+
19
+ Export all from `src/lib/main.js`:
20
+
21
+ - `createC64(opts?)` — create an emulator instance with default ROMs and 64KB RAM. Returns an object with `cpu`, `memory`, `vic`, `sid`, `cia1`, `cia2` subsystems.
22
+ - `loadPRG(c64, data)` — load a `.prg` file (Uint8Array) into memory at the address specified in its two-byte header.
23
+ - `step(c64)` — execute one CPU instruction, advance cycle count, and update timers. Returns the new state.
24
+ - `runFrame(c64)` — execute instructions for one video frame (~19656 cycles PAL). Trigger raster interrupts at the appropriate scanlines. Returns the framebuffer.
25
+ - `getFramebuffer(c64)` — return the current screen as a Uint8Array RGBA pixel buffer (320x200 or 384x272 with borders).
26
+ - `pressKey(c64, key)` / `releaseKey(c64, key)` — simulate keyboard input via CIA1 keyboard matrix.
27
+ - `joystickInput(c64, port, directions)` — set joystick state (up/down/left/right/fire) on port 1 or 2.
28
+ - `reset(c64)` — perform a hardware reset (set CPU to reset vector, clear state).
29
+
30
+ ## CPU Requirements
31
+
32
+ - All official 6502 opcodes (56 instructions, 151 opcode variants) with correct cycle counts.
33
+ - Decimal mode (BCD arithmetic) support.
34
+ - IRQ and NMI interrupt handling with correct stack behaviour.
35
+ - The 6510 I/O port at $00/$01 for ROM/RAM bank switching.
36
+ - Undocumented/illegal opcodes are NOT required (may be implemented as NOP).
37
+
38
+ ## Memory Map
39
+
40
+ - $0000–$00FF: Zero page
41
+ - $0100–$01FF: Stack
42
+ - $0200–$9FFF: Free RAM (programs load here)
43
+ - $A000–$BFFF: BASIC ROM (banked, RAM underneath)
44
+ - $C000–$CFFF: Free RAM
45
+ - $D000–$D3FF: VIC-II registers
46
+ - $D400–$D7FF: SID registers
47
+ - $D800–$DBFF: Colour RAM (nibbles)
48
+ - $DC00–$DCFF: CIA1 (keyboard, joystick, timer)
49
+ - $DD00–$DDFF: CIA2 (serial, timer, VIC bank)
50
+ - $E000–$FFFF: KERNAL ROM (banked, RAM underneath)
51
+
52
+ ## Video (VIC-II)
53
+
54
+ - Standard text mode (mode 0) — 40x25 characters, 16 colours, character ROM.
55
+ - Multicolour text mode.
56
+ - Standard bitmap mode (320x200) and multicolour bitmap mode (160x200).
57
+ - Hardware sprites (8 sprites, 24x21 pixels, multicolour optional).
58
+ - Raster interrupt — trigger IRQ at a programmable scanline.
59
+ - Border colour and background colour registers.
60
+ - Correct raster timing is essential — Lords of Midnight uses raster effects.
61
+
62
+ ## Sound (SID — basic)
63
+
64
+ - 3 oscillator voices with waveform selection (triangle, sawtooth, pulse, noise).
65
+ - ADSR envelope per voice.
66
+ - Frequency and pulse-width registers.
67
+ - Audio output as PCM sample buffer suitable for Web Audio API playback.
68
+ - Full filter emulation is NOT required (passthrough acceptable).
69
+
70
+ ## Input
71
+
72
+ - CIA1 keyboard matrix scan — map browser `KeyboardEvent` codes to the C64 8x8 keyboard matrix.
73
+ - Joystick via CIA1 ($DC01 port 1) and CIA1 ($DC00 port 2) — Lords of Midnight uses keyboard, but joystick support enables other games.
74
+
75
+ ## Lords of Midnight Compatibility
76
+
77
+ The target game exercises these specific features:
78
+ - Custom character sets (redefined at $3000 or similar)
79
+ - Full keyboard input (directional + action keys)
80
+ - Raster interrupts for split-screen effects
81
+ - IRQ-driven game loop timing via CIA timer
82
+ - PRG loading at the correct start address
83
+
84
+ ## Requirements
85
+
86
+ - No external dependencies for the core emulator (Web Audio API and Canvas API are browser-provided).
87
+ - KERNAL and BASIC ROMs must NOT be bundled (they are copyrighted). Provide a `loadROMs(c64, { kernal, basic, chargen })` function. Tests should use minimal stub ROMs.
88
+ - Comprehensive unit tests for each subsystem:
89
+ - CPU: test each addressing mode and instruction, verify cycle counts, test interrupt handling.
90
+ - Memory: test bank switching, I/O area mapping.
91
+ - VIC-II: test mode switching, framebuffer output for known register states.
92
+ - Input: test keyboard matrix encoding/decoding.
93
+ - Integration test: load a small test PRG that writes to screen memory and verify framebuffer output.
94
+ - README with architecture overview, usage example, and instructions for obtaining legal ROM dumps.
95
+
96
+ ## Acceptance Criteria
97
+
98
+ - [ ] CPU executes all 151 official opcodes with correct results and cycle counts
99
+ - [ ] CPU handles IRQ and NMI interrupts correctly (push PC+flags, jump to vector)
100
+ - [ ] Memory bank switching works ($01 register controls ROM/RAM visibility)
101
+ - [ ] VIC-II text mode renders 40x25 character display to framebuffer
102
+ - [ ] VIC-II raster interrupt fires at the programmed scanline
103
+ - [ ] SID produces audible waveform output for at least triangle and pulse waves
104
+ - [ ] CIA1 keyboard matrix correctly maps key presses to the scanned row/column
105
+ - [ ] `loadPRG()` places data at the correct address from the PRG header
106
+ - [ ] `runFrame()` executes approximately the right number of cycles per frame (PAL timing)
107
+ - [ ] A test PRG that writes "HELLO" to screen RAM ($0400) produces correct framebuffer output
108
+ - [ ] `reset()` returns the emulator to a known initial state
109
+ - [ ] All unit tests pass
110
+ - [ ] README documents architecture and ROM loading
@@ -0,0 +1,24 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>repository0</title>
7
+ <style>
8
+ body { font-family: system-ui, -apple-system, sans-serif; max-width: 800px; margin: 0 auto; padding: 2rem; color: #333; }
9
+ h1 { border-bottom: 2px solid #eee; padding-bottom: 0.5rem; }
10
+ a { color: #0366d6; }
11
+ .status { background: #f6f8fa; padding: 1rem; border-radius: 6px; margin: 1rem 0; }
12
+ </style>
13
+ </head>
14
+ <body>
15
+ <h1>repository0</h1>
16
+ <div class="status">
17
+ <p>This website is maintained by the autonomous pipeline. It showcases the library built from the project's mission.</p>
18
+ </div>
19
+ <h2>About</h2>
20
+ <p>See <a href="https://github.com/xn-intenton-z2a/repository0">the repository</a> for source code and mission details.</p>
21
+ <h2>Demo</h2>
22
+ <p><em>The pipeline will evolve this section to demonstrate the library's capabilities.</em></p>
23
+ </body>
24
+ </html>
@@ -5,16 +5,18 @@
5
5
  "type": "module",
6
6
  "main": "src/lib/main.js",
7
7
  "scripts": {
8
- "build": "echo \"Nothing to build\"",
8
+ "build": "npm run build:web",
9
+ "build:web": "mkdir -p docs && touch docs/.nojekyll && cp -r src/web/* docs/ 2>/dev/null || echo 'No web files to build'",
9
10
  "test": "vitest --run tests/unit/*.test.js",
10
11
  "test:unit": "vitest --run --coverage tests/unit/*.test.js",
11
- "start": "node src/lib/main.js"
12
+ "start": "node src/lib/main.js",
13
+ "start:web": "npx serve docs"
12
14
  },
13
15
  "keywords": [],
14
16
  "author": "",
15
17
  "license": "MIT",
16
18
  "dependencies": {
17
- "@xn-intenton-z2a/agentic-lib": "^7.1.62"
19
+ "@xn-intenton-z2a/agentic-lib": "^7.1.63"
18
20
  },
19
21
  "devDependencies": {
20
22
  "@vitest/coverage-v8": "^4.0.18",
@@ -0,0 +1,17 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // Copyright (C) 2025-2026 Polycode Limited
3
+ import { describe, test, expect } from "vitest";
4
+ import { readFileSync, existsSync } from "fs";
5
+
6
+ describe("Website", () => {
7
+ test("src/web/index.html exists", () => {
8
+ expect(existsSync("src/web/index.html")).toBe(true);
9
+ });
10
+
11
+ test("index.html contains valid HTML structure", () => {
12
+ const html = readFileSync("src/web/index.html", "utf8");
13
+ expect(html).toContain("<!DOCTYPE html>");
14
+ expect(html).toContain("<html");
15
+ expect(html).toContain("</html>");
16
+ });
17
+ });