Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ca2bc895fd
|
||
|
|
86646832e2
|
No files matched your search
@@ -0,0 +1,32 @@
|
||||
// ESLint flat config for the Jarvis File packages (`npm run lint` and each package's `lint` script).
|
||||
// ESLint's recommended rules only: correctness checks, no layout rules. The Node packages are CommonJS;
|
||||
// jarvis-file-core/js holds browser scripts that share globals through window.JF.
|
||||
import js from "@eslint/js";
|
||||
import globals from "globals";
|
||||
|
||||
export default [
|
||||
{
|
||||
ignores: ["**/node_modules/**", "**/dist/**", "**/coverage/**"],
|
||||
},
|
||||
js.configs.recommended,
|
||||
{
|
||||
rules: {
|
||||
// An underscore prefix marks a binding kept for the planned implementation but not used yet.
|
||||
"no-unused-vars": ["error", { argsIgnorePattern: "^_", varsIgnorePattern: "^_", caughtErrorsIgnorePattern: "^_" }],
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ["**/*.js"],
|
||||
languageOptions: {
|
||||
sourceType: "commonjs",
|
||||
globals: { ...globals.node },
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ["packages/jarvis-file-core/js/**/*.js"],
|
||||
languageOptions: {
|
||||
sourceType: "script",
|
||||
globals: { ...globals.browser },
|
||||
},
|
||||
},
|
||||
];
|
||||
Generated
+3073
File diff suppressed because it is too large.
Load diff
+6
-1
@@ -20,5 +20,10 @@
|
||||
"url": "git+https://github.com/KofTwentyTwo/jarvis-file.git"
|
||||
},
|
||||
"author": "KofTwentyTwo",
|
||||
"license": "MIT"
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^10.0.1",
|
||||
"eslint": "^10.14.0",
|
||||
"globals": "^17.14.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
"use strict";
|
||||
|
||||
const test = require("node:test");
|
||||
const assert = require("node:assert/strict");
|
||||
|
||||
const { compileRules } = require("../lib/rules-compiler");
|
||||
|
||||
const config = {
|
||||
auth: { allowedDomain: "example.com", ownerEmail: "owner@example.com" },
|
||||
project: { slug: "acme" },
|
||||
};
|
||||
|
||||
test("scopes every collection to the project slug", () => {
|
||||
const rules = compileRules(config);
|
||||
assert.match(rules, /match \/acme_comments\/\{commentId\}/);
|
||||
assert.match(rules, /match \/acme_jarvis_chats\/\{chatId\}/);
|
||||
});
|
||||
|
||||
test("restricts access to the allowed domain with the dots escaped", () => {
|
||||
const rules = compileRules(config);
|
||||
assert.match(rules, /matches\('\.\*@example\[\.\]com'\)/);
|
||||
assert.doesNotMatch(rules, /@example\.com'\)/);
|
||||
});
|
||||
|
||||
test("never allows deleting comments", () => {
|
||||
assert.match(compileRules(config), /allow delete: if false;/);
|
||||
});
|
||||
|
||||
test("fails loudly when the config has no auth section", () => {
|
||||
assert.throws(() => compileRules({ project: { slug: "acme" } }), TypeError);
|
||||
});
|
||||
@@ -0,0 +1,39 @@
|
||||
"use strict";
|
||||
|
||||
const test = require("node:test");
|
||||
const assert = require("node:assert/strict");
|
||||
const path = require("node:path");
|
||||
|
||||
const { resolveProjectDir } = require("../lib/validate-path");
|
||||
|
||||
test("resolves a simple name under the current working directory", () => {
|
||||
assert.equal(resolveProjectDir("my-project"), process.cwd() + path.sep + "my-project");
|
||||
});
|
||||
|
||||
test("trims surrounding whitespace", () => {
|
||||
assert.equal(resolveProjectDir(" docs "), process.cwd() + path.sep + "docs");
|
||||
});
|
||||
|
||||
test("rejects missing or non-string input", () => {
|
||||
for (const bad of [undefined, null, "", 42, {}]) {
|
||||
assert.throws(() => resolveProjectDir(bad), /required/);
|
||||
}
|
||||
});
|
||||
|
||||
test("rejects parent directory traversal", () => {
|
||||
for (const bad of ["..", "../evil", "a/../b", "..\\evil"]) {
|
||||
assert.throws(() => resolveProjectDir(bad), /Invalid project directory/);
|
||||
}
|
||||
});
|
||||
|
||||
test("rejects absolute paths", () => {
|
||||
for (const bad of ["/etc", "\\windows"]) {
|
||||
assert.throws(() => resolveProjectDir(bad), /Invalid project directory/);
|
||||
}
|
||||
});
|
||||
|
||||
test("rejects nested paths and invalid filesystem characters", () => {
|
||||
for (const bad of ["a/b", "a\\b", "a:b", "a<b", "a|b", "a?b", "a*b", "a\0b"]) {
|
||||
assert.throws(() => resolveProjectDir(bad), /Invalid project directory/);
|
||||
}
|
||||
});
|
||||
@@ -15,7 +15,7 @@ const { initFirestore } = require("./lib/firestore");
|
||||
|
||||
async function main() {
|
||||
const config = loadConfig();
|
||||
const db = initFirestore(config);
|
||||
const _db = initFirestore(config);
|
||||
|
||||
const crCollection = config.project.slug + "_change_requests";
|
||||
|
||||
|
||||
@@ -19,8 +19,8 @@ const { createClient } = require("./lib/anthropic");
|
||||
async function main() {
|
||||
const config = loadConfig();
|
||||
|
||||
const db = initFirestore(config);
|
||||
const claude = createClient(config);
|
||||
const _db = initFirestore(config);
|
||||
const _claude = createClient(config);
|
||||
|
||||
const commentsCollection = config.project.slug + "_comments";
|
||||
const chatCollection = config.project.slug + "_jarvis_chats";
|
||||
|
||||
@@ -12,11 +12,11 @@ const fs = require("fs");
|
||||
|
||||
/**
|
||||
* Extract text content from a specific section of an HTML file.
|
||||
* @param {string} htmlPath - Path to the HTML file
|
||||
* @param {string} sectionId - Section identifier to extract
|
||||
* @param {string} _htmlPath - Path to the HTML file
|
||||
* @param {string} _sectionId - Section identifier to extract
|
||||
* @returns {string} Plain text content of the section
|
||||
*/
|
||||
function extractSectionText(htmlPath, sectionId) {
|
||||
function extractSectionText(_htmlPath, _sectionId) {
|
||||
// TODO: Phase 1 -- implement HTML section text extraction
|
||||
// Parse HTML, find section by data-section-id or heading,
|
||||
// strip tags, return plain text for LLM context
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
"use strict";
|
||||
|
||||
const test = require("node:test");
|
||||
const assert = require("node:assert/strict");
|
||||
const fs = require("node:fs");
|
||||
const os = require("node:os");
|
||||
const path = require("node:path");
|
||||
|
||||
const { extractFullText } = require("../lib/context-reader");
|
||||
|
||||
function withTempFile(contents, run) {
|
||||
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "jarvis-context-"));
|
||||
const file = path.join(dir, "doc.html");
|
||||
fs.writeFileSync(file, contents);
|
||||
try {
|
||||
run(file);
|
||||
} finally {
|
||||
fs.rmSync(dir, { recursive: true, force: true });
|
||||
}
|
||||
}
|
||||
|
||||
test("strips tags, scripts and styles and normalizes whitespace", () => {
|
||||
const html = "<html><style>p{color:red}</style><body><h1>Title</h1>\n<p>Some <b>bold</b> text</p>" +
|
||||
"<script>alert(1)</script></body></html>";
|
||||
withTempFile(html, (file) => {
|
||||
assert.equal(extractFullText(file), "Title Some bold text");
|
||||
});
|
||||
});
|
||||
|
||||
test("decodes the common HTML entities", () => {
|
||||
withTempFile("<p>R&D <draft> done</p>", (file) => {
|
||||
assert.equal(extractFullText(file), "R&D <draft> done");
|
||||
});
|
||||
});
|
||||
|
||||
test("returns an empty string for a file that does not exist", () => {
|
||||
assert.equal(extractFullText(path.join(os.tmpdir(), "jarvis-no-such-file.html")), "");
|
||||
});
|
||||
Reference in new issue
Block a user