parallax-opencode 0.2.0

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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Master0fFate
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 ADDED
@@ -0,0 +1,217 @@
1
+ [![Parallax Banner](https://capsule-render.vercel.app/api?type=waving&height=200&color=6c63ff&desc=PARALLAX%20ENGINE&descAlignY=65&fontColor=ffffff&section=header&reversal=true&textBg=false&animation=fadeIn)](https://github.com/Master0fFate/parallax-opencode)
2
+
3
+ # PARALLAX ENGINE
4
+
5
+ **The first AI coding assistant that shows its work.**
6
+
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
8
+ [![OpenCode](https://img.shields.io/badge/OpenCode-plugin-6c63ff)](https://opencode.ai)
9
+ [![npm](https://img.shields.io/npm/v/parallax-opencode)](https://www.npmjs.com/package/parallax-opencode)
10
+ [![Tests](https://img.shields.io/badge/tests-30%20passing-brightgreen)]()
11
+ [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen)]()
12
+
13
+ ---
14
+
15
+ ## Quick Install
16
+
17
+ ```bash
18
+ # One command -- installs agent, plugin, skills, and dependencies
19
+ npx parallax-opencode
20
+ ```
21
+
22
+ After install, restart OpenCode and press **Tab** in the TUI to cycle to the Parallax agent.
23
+
24
+ ---
25
+
26
+ ## What Makes Parallax Different
27
+
28
+ Every AI coding tool (Cursor, Copilot, Windsurf) gives you code. None of them show you **how they got there**.
29
+
30
+ Parallax captures the complete reasoning trace of every session -- the ambiguity assessment, the invariants analysis, every verification result, every decision -- and makes it visible, exportable, and replayable.
31
+
32
+ Instead of "trust me, I wrote good code," Parallax says:
33
+
34
+ > "Here is my complete reasoning trace. Review it. Score it. Compare it with another approach. See for yourself."
35
+
36
+ ### The 4 Invariants
37
+
38
+ Every action is checked against four questions:
39
+
40
+ | Question | Why It Matters |
41
+ |---|---|
42
+ | Where does state live? | Ownership & truth, consistency, blast radius |
43
+ | Where does feedback live? | Observability, debugging, monitoring |
44
+ | What breaks if I delete this? | Coupling & fragility, safe refactoring |
45
+ | When does timing matter? | Async & ordering, race conditions, correctness |
46
+
47
+ ### The Coherence Score
48
+
49
+ After every session, Parallax computes an evidence-based quality score (0-100):
50
+
51
+ - **Protocol Coverage (30%)** -- Were all 5 protocol phases completed?
52
+ - **Verification Integrity (35%)** -- Pass rate on first attempt?
53
+ - **Edge Case Coverage (20%)** -- How many edge categories were analyzed?
54
+ - **Timing Discipline (15%)** -- Were phases in correct order?
55
+
56
+ Track your scores over time and see improvement:
57
+
58
+ ```bash
59
+ parallax trace trend
60
+ ```
61
+
62
+ ### The Trace Protocol
63
+
64
+ Every session produces a structured JSON trace file:
65
+
66
+ ```bash
67
+ parallax trace list
68
+ parallax trace show <session-id>
69
+ parallax trace score <session-id>
70
+ ```
71
+
72
+ Traces are stored in `.parallax/traces/` and can be attached to PRs, bug reports, or shared for review.
73
+
74
+ ### The Friction Loop
75
+
76
+ 1. After every write, Parallax auto-verifies (debounced)
77
+ 2. 3 retries before blocking further writes
78
+ 3. Parses verification output and reports specific failures
79
+ 4. Only the friction loop enforces quality -- the rest is instrumentation
80
+
81
+ ---
82
+
83
+ ## Comparison
84
+
85
+ | Feature | Plain OpenCode | Cursor | Copilot | Parallax |
86
+ |---|---|---|---|---|
87
+ | Structured reasoning trace | No | No | No | **Yes** |
88
+ | Exportable session history | No | No | No | **Yes** |
89
+ | Evidence-based quality score | No | No | No | **Yes** |
90
+ | Protocol enforcement | No | No | No | **Yes** |
91
+ | Mode switching (plan/build/debug) | No | No | No | **Yes** |
92
+ | CLI for trace analysis | No | No | No | **Yes** |
93
+
94
+ ---
95
+
96
+ ## Architecture
97
+
98
+ ```
99
+ Parallax Agent (system prompt)
100
+ |
101
+ +-- Plugin hooks
102
+ | event --> track session ID
103
+ | tool.execute.before --> block writes if friction exhausted
104
+ | tool.execute.after --> debounced auto-verify + trace recording
105
+ | system.transform --> inject protocol status + mode skill
106
+ | session.compacting --> preserve state + export trace
107
+ |
108
+ +-- Custom tools (7)
109
+ | parallax_verify auto-verify after writes
110
+ | parallax_analyze multi-perspective analysis
111
+ | parallax_checkin mark protocol step complete
112
+ | parallax_plan switch to PLAN mode
113
+ | parallax_build switch to BUILD mode
114
+ | parallax_debug switch to DEBUG mode
115
+ | parallax_trace_export export session trace to file
116
+ |
117
+ +-- CLI (parallax)
118
+ init create .parallax/ directory
119
+ trace list list all session traces
120
+ trace show <id> show trace details
121
+ trace score <id> show coherence score
122
+ trace export <id> export trace to JSON
123
+ trace trend show score trend
124
+ ```
125
+
126
+ ### Three Modes
127
+
128
+ | Mode | Tool | When |
129
+ |---|---|---|
130
+ | **PLAN** | `parallax_plan` | Vague requirements, before writing code |
131
+ | **BUILD** | `parallax_build` | Executing, writing code (default) |
132
+ | **DEBUG** | `parallax_debug` | Post-build quality and security audit |
133
+
134
+ ---
135
+
136
+ ## Manual Install (no npm)
137
+
138
+ ```bash
139
+ # Copy files directly
140
+ cp dist-standalone/parallax-engine.js ~/.config/opencode/plugins/
141
+ cp agents/parallax.md ~/.config/opencode/agents/
142
+ cp -r skills/parallax ~/.config/opencode/skills/
143
+ cp -r skills/parallax-plan ~/.config/opencode/skills/
144
+ cp -r skills/parallax-debug ~/.config/opencode/skills/
145
+
146
+ # Install runtime dependency
147
+ cd ~/.config/opencode && npm init -y && npm install @opencode-ai/plugin
148
+ ```
149
+
150
+ ---
151
+
152
+ ## Project Status
153
+
154
+ **Current phase: v0.2.0** -- Foundation + Trace Protocol
155
+
156
+ | Phase | Status | What |
157
+ |---|---|---|
158
+ | 0: Honest Foundation | Complete | MIT license, TS consolidation, 30 tests |
159
+ | 1: Trace Protocol | Complete | Trace recording, export, CLI, coherence score |
160
+ | 2: Quality Scoring | Complete | Score formula, trend tracking |
161
+ | 3: Git Integration | Planned | Commit trace links, PR-ready reports |
162
+ | 4: GitHub Excellence | In progress | README, CI/CD, docs |
163
+
164
+ ---
165
+
166
+ ## Commands
167
+
168
+ ### Plugin Tools (in OpenCode)
169
+
170
+ ```
171
+ parallax_verify Run project verification
172
+ parallax_analyze {topic} Structured multi-perspective analysis
173
+ parallax_checkin {step} Mark protocol step complete
174
+ parallax_plan Switch to PLAN mode
175
+ parallax_build Switch to BUILD mode
176
+ parallax_debug Switch to DEBUG mode
177
+ parallax_trace_export Export session trace to JSON
178
+ ```
179
+
180
+ ### CLI (terminal)
181
+
182
+ ```
183
+ parallax init Create .parallax/ directory
184
+ parallax trace list List all traces
185
+ parallax trace show <id> Show trace details
186
+ parallax trace score <id> Show coherence score breakdown
187
+ parallax trace export <id> Export trace as pretty JSON
188
+ parallax trace trend Show score trend over time
189
+ ```
190
+
191
+ ---
192
+
193
+ ## Files
194
+
195
+ ```
196
+ parallax_plugin/
197
+ agents/parallax.md # Primary agent definition
198
+ src/plugin.ts # Canonical plugin (TypeScript)
199
+ src/types.ts # Shared type definitions
200
+ src/detect.ts # Project detection
201
+ src/trace.ts # Trace recording and export
202
+ src/score.ts # Coherence score computation
203
+ src/cli.ts # CLI entry point
204
+ src/tests/ # 30 tests across 5 files
205
+ dist/ # Compiled output
206
+ dist-standalone/ # Standalone plugin file
207
+ skills/ # Protocol skills
208
+ scripts/ # Install and publish scripts
209
+ package.json # npm package metadata
210
+ LICENSE # MIT
211
+ ```
212
+
213
+ ---
214
+
215
+ ## License
216
+
217
+ MIT &copy; [@Master0fFate](https://github.com/Master0fFate)
@@ -0,0 +1,100 @@
1
+ ---
2
+ name: Parallax
3
+ description: "PARALLAX ENGINE: Multi-perspective AI coding agent with friction-loop verification, the 4 invariants framework, and parallax planning protocol. Views every problem from every angle before acting. Best for complex engineering work requiring depth and correctness."
4
+ mode: primary
5
+ color: "#6c63ff"
6
+ permission:
7
+ edit: allow
8
+ bash: ask
9
+ read: allow
10
+ grep: allow
11
+ glob: allow
12
+ list: allow
13
+ webfetch: allow
14
+ todowrite: allow
15
+ ---
16
+
17
+ You are PARALLAX -- a systems thinking partner for experienced developers.
18
+
19
+ ## CORE DIRECTIVE
20
+
21
+ YOU MUST follow the Parallax Engine protocol for EVERY task in order. The plugin tracks compliance and will block writes if critical steps are skipped.
22
+
23
+ ## MANDATORY PROTOCOL -- Follow in order for EVERY task
24
+
25
+ ### STEP 1: AMBIGUITY CHECK [REQUIRED - FIRST THING]
26
+ Output your ambiguity assessment BEFORE anything else:
27
+ - HIGH (vague/conceptual): User MUST ask 3+ clarifying questions. Do NOT proceed until ambiguity resolved.
28
+ - MEDIUM (some gaps): Ask targeted questions. If you must assume an unstated pattern, it's MEDIUM.
29
+ - LOW (clear/specific): Verify quickly and proceed. Trivial changes skip to Step 4.
30
+
31
+ CONSEQUENCE: Plugin will block writes if this step is skipped.
32
+
33
+ ### STEP 2: 4 INVARIANTS [REQUIRED - BEFORE ANY CODE]
34
+ State each answer explicitly:
35
+ | Question | Your answer |
36
+ |---|---|
37
+ | Where does state live? | ownership & truth |
38
+ | Where does feedback live? | observability |
39
+ | What breaks if I delete this? | coupling & fragility |
40
+ | When does timing matter? | async & correctness |
41
+
42
+ ### STEP 3: VERIFICATION GATE [REQUIRED - BEFORE FIRST WRITE]
43
+ Check every box. Flag any "no" as a risk:
44
+ - [ ] State ownership and consistency clear?
45
+ - [ ] Feedback / observability in place?
46
+ - [ ] Blast radius understood?
47
+ - [ ] Timing & ordering safe?
48
+ - [ ] Follows existing patterns (or intentionally breaks them)?
49
+ - [ ] Security / obvious risks addressed?
50
+
51
+ ### STEP 4: EXECUTE
52
+ Write code. Use parallax_verify after writes. Fix failures. Do NOT work around the plugin.
53
+
54
+ ### STEP 5: COMMIT DECISION [REQUIRED]
55
+ State one:
56
+ - Full Coherence -- Ship complete solution
57
+ - Pragmatic Partial -- Ship core + flag deferred items
58
+ - Hold + Clarify -- Critical gaps remain
59
+ - User Override -- "Ship it" = proceed with risks flagged
60
+
61
+ ### STEP 6: SUMMARIZE [REQUIRED]
62
+ After finishing, output:
63
+ - What was built
64
+ - Edge cases handled
65
+ - Verification passed?
66
+ - Remaining concerns
67
+
68
+ ## MODES
69
+
70
+ Use these tools to load specialized skills for each phase:
71
+
72
+ | Mode | Tool | Phase | Loads |
73
+ |---|---|---|---|
74
+ | PLAN | parallax_plan | Steps 1-3 | Precision Architect |
75
+ | BUILD | parallax_build | Step 4 | Standard protocol (default) |
76
+ | DEBUG | parallax_debug | Step 6 | Universal Auditor |
77
+
78
+ ## TOOLS
79
+
80
+ - parallax_verify -- Run project verification (use instead of bash)
81
+ - parallax_analyze -- Structured multi-perspective analysis
82
+ - parallax_plan -- Switch to PLAN mode
83
+ - parallax_build -- Switch to BUILD mode
84
+ - parallax_debug -- Switch to DEBUG mode
85
+ - parallax_checkin -- Mark a protocol step complete (plugin tracks this)
86
+ - parallax_trace_export -- Export session trace to JSON file (includes coherence score)
87
+
88
+ ## RED LINES (Stop Immediately)
89
+
90
+ - Unclear state ownership
91
+ - Unknown blast radius
92
+ - Timing / race condition hazards
93
+ - Security issues
94
+ - Creating significant complexity debt
95
+ - Unknown unknowns on non-trivial changes
96
+
97
+ ## OUTPUT RULES
98
+
99
+ - Terminal environment. No markdown rendering. No emojis. Plain ASCII.
100
+ - ALL CAPS for emphasis, [brackets] for labels, indentation for structure.
package/dist/cli.d.ts ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * PARALLAX ENGINE -- CLI Entry Point
4
+ *
5
+ * Provides the `parallax` CLI command for trace management, scoring,
6
+ * and project initialization.
7
+ *
8
+ * Commands:
9
+ * parallax init - Create .parallax/ config directory
10
+ * parallax trace list - List all traces
11
+ * parallax trace show <id> - Show a trace
12
+ * parallax trace score <id> - Show coherence score breakdown
13
+ * parallax trace export <id> - Export trace to JSON
14
+ * parallax trace trend - Show score trend
15
+ *
16
+ * License: MIT
17
+ * Copyright (c) 2026 Master0fFate
18
+ */
19
+ export declare function main(): Promise<number>;
package/dist/cli.js ADDED
@@ -0,0 +1,236 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * PARALLAX ENGINE -- CLI Entry Point
4
+ *
5
+ * Provides the `parallax` CLI command for trace management, scoring,
6
+ * and project initialization.
7
+ *
8
+ * Commands:
9
+ * parallax init - Create .parallax/ config directory
10
+ * parallax trace list - List all traces
11
+ * parallax trace show <id> - Show a trace
12
+ * parallax trace score <id> - Show coherence score breakdown
13
+ * parallax trace export <id> - Export trace to JSON
14
+ * parallax trace trend - Show score trend
15
+ *
16
+ * License: MIT
17
+ * Copyright (c) 2026 Master0fFate
18
+ */
19
+ import { existsSync, mkdirSync, writeFileSync } from "fs";
20
+ import { join } from "path";
21
+ import { listTraceFiles, loadTrace, exportTrace, } from "./trace";
22
+ import { computeCoherenceScore, formatScoreBreakdown, readScoreHistory, sparkline, scoreToGrade, recordScore, } from "./score";
23
+ // ---------------------------------------------------------------------------
24
+ // Constants
25
+ // ---------------------------------------------------------------------------
26
+ const PARALLAX_DIR = ".parallax";
27
+ // ---------------------------------------------------------------------------
28
+ // Help & version
29
+ // ---------------------------------------------------------------------------
30
+ function showHelp() {
31
+ console.log(`Parallax Engine CLI v0.2.0`);
32
+ console.log(``);
33
+ console.log(`Usage: parallax <command> [options]`);
34
+ console.log(``);
35
+ console.log(`Commands:`);
36
+ console.log(` init Create .parallax/ directory with defaults`);
37
+ console.log(` trace list List all traces`);
38
+ console.log(` trace show <id> Show full trace`);
39
+ console.log(` trace score <id> Show coherence score`);
40
+ console.log(` trace export <id> Export trace to JSON file`);
41
+ console.log(` trace trend Show score trend over time`);
42
+ console.log(` help Show this help`);
43
+ }
44
+ function showVersion() {
45
+ console.log("0.2.0");
46
+ }
47
+ // ---------------------------------------------------------------------------
48
+ // Command implementations
49
+ // ---------------------------------------------------------------------------
50
+ async function cmdInit() {
51
+ const dir = join(process.cwd(), PARALLAX_DIR);
52
+ if (!existsSync(dir)) {
53
+ mkdirSync(dir, { recursive: true });
54
+ console.log(`Created ${PARALLAX_DIR}/`);
55
+ }
56
+ else {
57
+ console.log(`${PARALLAX_DIR}/ already exists`);
58
+ }
59
+ const gitignorePath = join(dir, ".gitignore");
60
+ if (!existsSync(gitignorePath)) {
61
+ writeFileSync(gitignorePath, "*\n", "utf8");
62
+ console.log(`Created ${PARALLAX_DIR}/.gitignore`);
63
+ }
64
+ // Create traces subdirectory
65
+ const tracesDir = join(dir, "traces");
66
+ if (!existsSync(tracesDir)) {
67
+ mkdirSync(tracesDir, { recursive: true });
68
+ console.log(`Created ${PARALLAX_DIR}/traces/`);
69
+ }
70
+ console.log(`\nParallax initialized. Traces will be stored in ${PARALLAX_DIR}/traces/`);
71
+ return 0;
72
+ }
73
+ async function cmdTraceList() {
74
+ const files = listTraceFiles();
75
+ if (files.length === 0) {
76
+ console.log("No traces found.");
77
+ return 0;
78
+ }
79
+ console.log(`Found ${files.length} trace(s):\n`);
80
+ for (const f of files) {
81
+ const trace = loadTrace(f.sessionId);
82
+ const score = trace ? computeCoherenceScore(trace) : null;
83
+ const phases = trace ? trace.phases.length : 0;
84
+ const writes = trace ? trace.writes.length : 0;
85
+ const scoreStr = score ? `${score.total}/100 (${scoreToGrade(score.total)})` : "N/A";
86
+ console.log(` ${f.sessionId.padEnd(20)} ` +
87
+ `${writes} writes, ${phases} phases ` +
88
+ `Score: ${scoreStr}`);
89
+ }
90
+ return 0;
91
+ }
92
+ async function cmdTraceShow(id) {
93
+ const trace = loadTrace(id);
94
+ if (!trace) {
95
+ console.error(`Trace not found: ${id}`);
96
+ return 1;
97
+ }
98
+ console.log(`Session: ${trace.session.id}`);
99
+ console.log(`Started: ${trace.session.startedAt}`);
100
+ console.log(`Ended: ${trace.session.endedAt || "in progress"}`);
101
+ console.log(`Project: ${trace.session.project || "unknown"}`);
102
+ console.log(`Type: ${trace.session.projectType || "unknown"}`);
103
+ console.log(``);
104
+ console.log(`Phases (${trace.phases.length}):`);
105
+ for (const p of trace.phases) {
106
+ console.log(` [${p.phase}] ${p.timestamp}`);
107
+ if (Object.keys(p.data).length > 0) {
108
+ console.log(` Data: ${JSON.stringify(p.data)}`);
109
+ }
110
+ }
111
+ console.log(``);
112
+ console.log(`Writes (${trace.writes.length}):`);
113
+ for (const w of trace.writes) {
114
+ const status = w.verification === "pass" ? "OK" : w.verification === "fail" ? "FAIL" : w.verification;
115
+ console.log(` [${status}] ${w.file} (retries: ${3 - w.frictionRetriesLeft})`);
116
+ }
117
+ return 0;
118
+ }
119
+ async function cmdTraceScore(id) {
120
+ const trace = loadTrace(id);
121
+ if (!trace) {
122
+ console.error(`Trace not found: ${id}`);
123
+ return 1;
124
+ }
125
+ const breakdown = computeCoherenceScore(trace);
126
+ console.log(formatScoreBreakdown(breakdown));
127
+ // Optionally record the score
128
+ const entry = {
129
+ sessionId: id,
130
+ date: new Date().toISOString(),
131
+ score: breakdown.total,
132
+ project: trace.session.project,
133
+ };
134
+ recordScore(entry);
135
+ return 0;
136
+ }
137
+ async function cmdTraceExport(id) {
138
+ const trace = loadTrace(id);
139
+ if (!trace) {
140
+ console.error(`Trace not found: ${id}`);
141
+ return 1;
142
+ }
143
+ const filePath = exportTrace(id, true);
144
+ console.log(`Trace exported to: ${filePath}`);
145
+ return 0;
146
+ }
147
+ async function cmdTraceTrend() {
148
+ const history = readScoreHistory();
149
+ if (history.length === 0) {
150
+ console.log("No score history found.");
151
+ return 0;
152
+ }
153
+ const scores = history.map((e) => e.score);
154
+ const line = sparkline(scores);
155
+ const avg = Math.round(scores.reduce((a, b) => a + b, 0) / scores.length);
156
+ console.log(`Score trend (${history.length} entries, avg: ${avg}/100):`);
157
+ console.log(` ${line}`);
158
+ console.log(``);
159
+ for (const entry of history) {
160
+ const date = entry.date.slice(0, 10);
161
+ console.log(` ${date} ${entry.score}/100 [${entry.sessionId.slice(0, 8)}] ${entry.project || ""}`);
162
+ }
163
+ return 0;
164
+ }
165
+ // ---------------------------------------------------------------------------
166
+ // Command routing
167
+ // ---------------------------------------------------------------------------
168
+ export async function main() {
169
+ const args = process.argv.slice(2);
170
+ if (args.length === 0) {
171
+ showHelp();
172
+ return 0;
173
+ }
174
+ const cmd = args[0];
175
+ switch (cmd) {
176
+ case "help":
177
+ showHelp();
178
+ return 0;
179
+ case "version":
180
+ case "--version":
181
+ case "-v":
182
+ showVersion();
183
+ return 0;
184
+ case "init":
185
+ return cmdInit();
186
+ case "trace": {
187
+ const sub = args[1];
188
+ switch (sub) {
189
+ case "list":
190
+ return cmdTraceList();
191
+ case "show":
192
+ if (!args[2]) {
193
+ console.error("Usage: parallax trace show <session-id>");
194
+ return 1;
195
+ }
196
+ return cmdTraceShow(args[2]);
197
+ case "score":
198
+ if (!args[2]) {
199
+ console.error("Usage: parallax trace score <session-id>");
200
+ return 1;
201
+ }
202
+ return cmdTraceScore(args[2]);
203
+ case "export":
204
+ if (!args[2]) {
205
+ console.error("Usage: parallax trace export <session-id>");
206
+ return 1;
207
+ }
208
+ return cmdTraceExport(args[2]);
209
+ case "trend":
210
+ return cmdTraceTrend();
211
+ default:
212
+ console.error(`Unknown trace command: ${sub}`);
213
+ console.error("Usage: parallax trace <list|show|score|export|trend>");
214
+ return 1;
215
+ }
216
+ }
217
+ default:
218
+ console.error(`Unknown command: ${cmd}`);
219
+ console.error("Run 'parallax help' for usage.");
220
+ return 1;
221
+ }
222
+ }
223
+ // Run the CLI if this is the entry point
224
+ // Detected by checking if process.argv[1] ends with cli.ts or cli.js
225
+ const isMain = process.argv[1]?.endsWith("cli.ts") ||
226
+ process.argv[1]?.endsWith("cli.js") ||
227
+ process.argv[1]?.endsWith("parallax-engine") ||
228
+ process.argv[1]?.endsWith("parallax-engine.js");
229
+ if (isMain) {
230
+ main()
231
+ .then((code) => process.exit(code))
232
+ .catch((err) => {
233
+ console.error(err);
234
+ process.exit(1);
235
+ });
236
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * PARALLAX ENGINE -- Project Detection
3
+ *
4
+ * Detects the project type in the current working directory and returns
5
+ * the appropriate verification command.
6
+ *
7
+ * License: MIT
8
+ * Copyright (c) 2026 Master0fFate
9
+ */
10
+ import type { ProjectType, VerifyResult } from "./types";
11
+ /**
12
+ * Detect the project type based on files present in the current directory.
13
+ */
14
+ export declare function detectProject(): ProjectType;
15
+ /**
16
+ * Get the shell command string for verification based on project type.
17
+ */
18
+ export declare function getVerifyCommand(): string | null;
19
+ /**
20
+ * Run the verification command synchronously using Bun.spawnSync.
21
+ * Returns null if no known project type is detected.
22
+ */
23
+ export declare function runVerify(): VerifyResult | null;
package/dist/detect.js ADDED
@@ -0,0 +1,65 @@
1
+ /**
2
+ * PARALLAX ENGINE -- Project Detection
3
+ *
4
+ * Detects the project type in the current working directory and returns
5
+ * the appropriate verification command.
6
+ *
7
+ * License: MIT
8
+ * Copyright (c) 2026 Master0fFate
9
+ */
10
+ import { existsSync, statSync } from "fs";
11
+ /**
12
+ * Detect the project type based on files present in the current directory.
13
+ */
14
+ export function detectProject() {
15
+ try {
16
+ if (existsSync("Cargo.toml"))
17
+ return "cargo";
18
+ if (existsSync("package.json")) {
19
+ if (existsSync("node_modules") && statSync("node_modules").isDirectory()) {
20
+ if (existsSync("tsconfig.json"))
21
+ return "tsc";
22
+ return "lint";
23
+ }
24
+ }
25
+ if (existsSync("pyproject.toml") || existsSync("requirements.txt"))
26
+ return "python";
27
+ return null;
28
+ }
29
+ catch {
30
+ return null;
31
+ }
32
+ }
33
+ /**
34
+ * Get the shell command string for verification based on project type.
35
+ */
36
+ export function getVerifyCommand() {
37
+ switch (detectProject()) {
38
+ case "cargo": return "cargo check --color=never --all-targets --all-features 2>&1";
39
+ case "tsc": return "npx tsc --noEmit 2>&1";
40
+ case "lint": return "npm run lint 2>&1";
41
+ case "python": return "python -m compileall -q . 2>&1";
42
+ default: return null;
43
+ }
44
+ }
45
+ /**
46
+ * Run the verification command synchronously using Bun.spawnSync.
47
+ * Returns null if no known project type is detected.
48
+ */
49
+ export function runVerify() {
50
+ try {
51
+ const cmd = getVerifyCommand();
52
+ if (!cmd)
53
+ return null;
54
+ const shell = process.platform === "win32" ? "cmd" : "sh";
55
+ const flag = process.platform === "win32" ? "/C" : "-c";
56
+ const proc = Bun.spawnSync([shell, flag, cmd], { cwd: process.cwd() });
57
+ const stdout = proc.stdout.toString();
58
+ const stderr = proc.stderr.toString();
59
+ const combined = stderr ? `${stdout}\n${stderr}` : stdout;
60
+ return { exitCode: proc.exitCode, stdout, stderr, combined };
61
+ }
62
+ catch (e) {
63
+ return { exitCode: -1, stdout: "", stderr: String(e), combined: String(e) };
64
+ }
65
+ }