diff --git a/.backlog/config.yml b/.backlog/config.yml
new file mode 100644
index 00000000..4da91d7f
--- /dev/null
+++ b/.backlog/config.yml
@@ -0,0 +1,14 @@
+project_name: "platformos-tools"
+default_status: "To Do"
+statuses: ["To Do", "In Progress", "Done"]
+labels: []
+date_format: yyyy-mm-dd
+max_column_width: 20
+auto_open_browser: true
+default_port: 6420
+remote_operations: true
+auto_commit: false
+bypass_git_hooks: false
+check_active_branches: true
+active_branch_days: 30
+task_prefix: "task"
diff --git a/.backlog/tasks/task-1 - Mirror-backend-FULL_PHYSICAL_PATH-regexps-in-path-utils.ts.md b/.backlog/tasks/task-1 - Mirror-backend-FULL_PHYSICAL_PATH-regexps-in-path-utils.ts.md
new file mode 100644
index 00000000..852e3547
--- /dev/null
+++ b/.backlog/tasks/task-1 - Mirror-backend-FULL_PHYSICAL_PATH-regexps-in-path-utils.ts.md
@@ -0,0 +1,38 @@
+---
+id: TASK-1
+title: Mirror backend FULL_PHYSICAL_PATH regexps in path-utils.ts
+status: To Do
+assignee: []
+created_date: '2026-05-11 12:48'
+labels: []
+dependencies: []
+---
+
+## Description
+
+
+Replace the current FILE_TYPE_DIRS + TYPE_MATCHERS in `packages/platformos-common/src/path-utils.ts` with a declarative table that is a 1:1 mirror of the backend `converters_config.rb` regexps. The linter must classify a file iff the backend would dispatch that file to a converter.
+
+**Source of truth:** `desksnearme/app/services/app_builder/services/converters_config.rb` plus per-model `PATH_DIRECTORY` / `EXTENSION` / `PHYSICAL_PATH` constants under `desksnearme/app/models/`. Helpful header is `desksnearme/app/models/concerns/deployable.rb` (lines 20–22) which builds `FULL_PHYSICAL_PATH = \A + DIR_PREFIX + PHYSICAL_PATH`.
+
+**Scope:**
+- Drop `marketplace_builder` support entirely (user-approved). Only `app/` and `modules/{name}/{access}/` (plus optional `app/modules/{name}/{access}/`).
+- Replace the dir-name-only matchers with full FULL_PHYSICAL_PATH regexps. This catches wrong extensions (e.g. `app/translations/en.json` → undefined) the way the backend does.
+- Keep `getFileType`, `getAppPaths`, `getModulePaths` signatures stable; re-derive their data from a single `BACKEND_MODELS` table.
+- Mirror backend quirks verbatim with `// backend quirk:` comments: GraphQuery `(graph_queries|graphql)s?` and DIR_PREFIX `modules/(.+)(private|public)/` missing-slash shape.
+- Update `RouteTable.extractRelativePagePath` to drop the `marketplace_builder` alternative.
+
+**Files:**
+- `packages/platformos-common/src/path-utils.ts`
+- `packages/platformos-common/src/route-table/RouteTable.ts` (drop `marketplace_builder` from regex)
+- `packages/platformos-common/CLAUDE.md` (update architecture note)
+
+
+## Acceptance Criteria
+
+- [ ] #1 BACKEND_MODELS table mirrors every row in converters_config.rb (Page, InstanceView Page/Layout/Partial split, GraphQuery, AuthorizationPolicy, EmailNotification, ApiCallNotification, SmsNotification, DataMigration, FormConfiguration, Translation, TransactableType, CustomModelType, InstanceProfileType, Asset)
+- [ ] #2 DIR_PREFIX accepts only: empty | app/ | modules/{name}/{public|private}/ | app/modules/{name}/{public|private}/. marketplace_builder removed everywhere
+- [ ] #3 FULL_PHYSICAL_PATH regex includes the extension suffix where the backend enforces it (.liquid for Liquid types, .graphql for GraphQL, .yml for YAML types)
+- [ ] #4 Each BACKEND_MODELS row carries a comment pointing to the exact backend model file:line it mirrors
+- [ ] #5 RouteTable.extractRelativePagePath drops the marketplace_builder regex alternative
+
diff --git a/.backlog/tasks/task-2 - Add-scalar-pattern-ActivityStreams-file-types.md b/.backlog/tasks/task-2 - Add-scalar-pattern-ActivityStreams-file-types.md
new file mode 100644
index 00000000..f7368872
--- /dev/null
+++ b/.backlog/tasks/task-2 - Add-scalar-pattern-ActivityStreams-file-types.md
@@ -0,0 +1,44 @@
+---
+id: TASK-2
+title: Add scalar-pattern + ActivityStreams file types
+status: To Do
+assignee: []
+created_date: '2026-05-11 13:02'
+labels: []
+dependencies:
+ - TASK-1
+---
+
+## Description
+
+
+Add new `PlatformOSFileType` enum values for files that converters_config.rb matches with scalar/literal patterns rather than per-model FULL_PHYSICAL_PATH, plus the two ActivityStreams subtypes the backend dispatches.
+
+**New enum values:**
+- `InstanceConfig` — `^/?(app/)?config\.yml$` (drops marketplace_builder)
+- `UserType` — `\A(app/)?user\.yml`
+- `AssetManifest` — `\A(app/)?asset_manifest\.json`
+- `AssetsManifest` — `\A(app/|modules/(.+)(private|public)/)assets\.json`
+- `ModulesLock` — `^/?(?:(?:app/)?pos-modules\.lock\.json|pos-module\.lock\.json)$`
+- `ActivityStreamsHandler` — `activity_streams/handlers/(.+)\.yml`
+- `ActivityStreamsGroupingHandler` — `activity_streams/grouping_handlers/(.+)\.yml`
+
+**Source:** `converters_config.rb` lines 7–22 (scalar patterns) plus `app/models/activity_streams/handler.rb` and `app/models/activity_streams/grouping_handler.rb`.
+
+**Design notes:**
+- ActivityStreams types extend the `BACKEND_MODELS` table from task 1 (they have normal `PHYSICAL_PATH`).
+- Scalar patterns live in a small separate `SCALAR_MATCHERS` table. `getFileType` consults `TYPE_MATCHERS` first, then `SCALAR_MATCHERS`.
+- Add `ActivityStreamsHandler` and `ActivityStreamsGroupingHandler` to `YAML_FILE_TYPES`.
+- Scalar JSON types (`AssetManifest`, `AssetsManifest`, `ModulesLock`) get classified but are NOT in `YAML_FILE_TYPES` — `isSupportedSourceFile` returns false for them (no JSON checks yet).
+
+**Files:**
+- `packages/platformos-common/src/path-utils.ts`
+
+
+## Acceptance Criteria
+
+- [ ] #1 Seven new PlatformOSFileType enum values added with backend file:line references
+- [ ] #2 getFileType correctly classifies: config.yml, app/config.yml, user.yml, app/user.yml, asset_manifest.json, app/asset_manifest.json, app/assets.json, modules/core/public/assets.json, pos-modules.lock.json, pos-module.lock.json, app/pos-modules.lock.json
+- [ ] #3 ActivityStreamsHandler and ActivityStreamsGroupingHandler classify under app/, modules/, and app/modules/ roots
+- [ ] #4 YAML_FILE_TYPES set updated to include ActivityStreamsHandler and ActivityStreamsGroupingHandler
+
diff --git a/.backlog/tasks/task-3 - Rewrite-isSupportedSourceFile-to-be-type-driven.md b/.backlog/tasks/task-3 - Rewrite-isSupportedSourceFile-to-be-type-driven.md
new file mode 100644
index 00000000..a6886578
--- /dev/null
+++ b/.backlog/tasks/task-3 - Rewrite-isSupportedSourceFile-to-be-type-driven.md
@@ -0,0 +1,48 @@
+---
+id: TASK-3
+title: Rewrite isSupportedSourceFile to be type-driven
+status: To Do
+assignee: []
+created_date: '2026-05-11 13:09'
+labels: []
+dependencies:
+ - TASK-2
+---
+
+## Description
+
+
+Stop dispatching `isSupportedSourceFile` on file extension first. The current implementation in `packages/platformos-common/src/path-utils.ts` (line 273) duplicates type-membership decisions across three branches. After tasks 1+2 land, replace it with a single type-driven decision that defers to `getFileType` and the LIQUID/GRAPHQL/YAML sets.
+
+**Target behavior:**
+```ts
+export function isSupportedSourceFile(uri: UriString): boolean {
+ // Asset partials are compiled by the backend but the linter cannot parse
+ // them as Liquid — they are CSS/JS/SCSS templates.
+ if (/\.(?:s?css|js)\.liquid$/.test(uri)) return false;
+ const type = getFileType(uri);
+ if (type === undefined) return false;
+ if (LIQUID_FILE_TYPES.has(type)) return uri.endsWith('.liquid');
+ if (GRAPHQL_FILE_TYPES.has(type)) return true; // extension enforced by FULL_PHYSICAL_PATH
+ if (YAML_FILE_TYPES.has(type)) return true; // extension enforced by FULL_PHYSICAL_PATH
+ return false; // Asset, scalar JSON types, etc.
+}
+```
+
+**Why the `.liquid` gate stays for Liquid types:** backend `PHYSICAL_PATH` for `Page` and `InstanceView` accepts any extension (`(.+)` with no `\.liquid\z` anchor), so the regex alone is not enough to know whether the linter can parse it.
+
+**Why GraphQL/YAML don't need an extension gate:** their FULL_PHYSICAL_PATH already enforces `\.graphql\z` or `\.yml\z`.
+
+**Files:**
+- `packages/platformos-common/src/path-utils.ts`
+
+**Optional cleanup:** `isKnownLiquidFile`, `isKnownGraphQLFile`, `isKnownYAMLFile` become thin wrappers over `getFileType` + a type-set lookup. Keep exported for back-compat; mark `isSupportedSourceFile` as preferred.
+
+
+## Acceptance Criteria
+
+- [ ] #1 isSupportedSourceFile uses getFileType + type-set membership; no extension-based dispatch except the asset-partial skip and the Page/InstanceView .liquid gate
+- [ ] #2 Returns false for Asset, AssetManifest, AssetsManifest, ModulesLock, InstanceConfig, UserType
+- [ ] #3 Returns false for app/views/partials/foo.css.liquid (asset partial in known dir)
+- [ ] #4 Returns true for app/views/pages/home.liquid and false for app/views/pages/home.txt
+
diff --git a/.backlog/tasks/task-4 - Replace-inlined-extension-filters-with-isSupportedSourceFile.md b/.backlog/tasks/task-4 - Replace-inlined-extension-filters-with-isSupportedSourceFile.md
new file mode 100644
index 00000000..2753c84e
--- /dev/null
+++ b/.backlog/tasks/task-4 - Replace-inlined-extension-filters-with-isSupportedSourceFile.md
@@ -0,0 +1,53 @@
+---
+id: TASK-4
+title: Replace inlined extension filters with isSupportedSourceFile
+status: To Do
+assignee: []
+created_date: '2026-05-11 13:10'
+labels: []
+dependencies:
+ - TASK-3
+---
+
+## Description
+
+
+Now that `isSupportedSourceFile` is the single source of truth (task 3), eliminate the two callers that hand-roll a subset of its logic.
+
+**Caller 1 — `packages/platformos-check-node/src/index.ts:144-163`**
+
+Current code inside `getApp().glob().filter(...)`:
+```ts
+if (filePath.endsWith('.liquid') && !isKnownLiquidFile(filePath)) return false;
+if (filePath.endsWith('.graphql') && !isKnownGraphQLFile(filePath)) return false;
+if ((filePath.endsWith('.yml') || filePath.endsWith('.yaml')) && !isKnownYAMLFile(filePath)) return false;
+return true;
+```
+Replace with:
+```ts
+if (!isSupportedSourceFile(filePath)) return false;
+return true;
+```
+Also drop the now-unused `isKnownLiquidFile`, `isKnownGraphQLFile`, `isKnownYAMLFile` imports.
+
+**Caller 2 — `packages/platformos-language-server-common/src/documents/DocumentManager.ts:84-89`**
+
+Current:
+```ts
+.filter(sourceCode => sourceCode.type !== SourceCodeType.LiquidHtml || isKnownLiquidFile(sourceCode.uri))
+```
+This only filters Liquid; GraphQL and YAML files outside known dirs slip through. Replace with `isSupportedSourceFile(sourceCode.uri)` so the LSP `app()` view matches what the CLI sees.
+
+**Behavior change to note:** `DocumentManager.app()` will now drop graphql/yaml files that sit outside known dirs. If any LSP test depends on a misplaced fixture being included, update the fixture path.
+
+**Files:**
+- `packages/platformos-check-node/src/index.ts`
+- `packages/platformos-language-server-common/src/documents/DocumentManager.ts`
+
+
+## Acceptance Criteria
+
+- [ ] #1 platformos-check-node/src/index.ts uses isSupportedSourceFile and drops the three isKnown* imports
+- [ ] #2 DocumentManager.app() uses isSupportedSourceFile uniformly
+- [ ] #3 yarn build succeeds for both packages with no unused-import errors
+
diff --git a/.backlog/tasks/task-5 - Update-path-utils-spec-for-backend-mirror-behavior.md b/.backlog/tasks/task-5 - Update-path-utils-spec-for-backend-mirror-behavior.md
new file mode 100644
index 00000000..c946da85
--- /dev/null
+++ b/.backlog/tasks/task-5 - Update-path-utils-spec-for-backend-mirror-behavior.md
@@ -0,0 +1,62 @@
+---
+id: TASK-5
+title: Update path-utils spec for backend-mirror behavior
+status: To Do
+assignee: []
+created_date: '2026-05-11 13:10'
+labels: []
+dependencies:
+ - TASK-3
+---
+
+## Description
+
+
+Rewrite `packages/platformos-common/src/path-utils.spec.ts` to assert the new (stricter, backend-exact) semantics.
+
+**Remove:**
+- The entire `describe('marketplace_builder/ legacy root', ...)` block.
+- All other `marketplace_builder/...` assertions sprinkled through other describes (search for the literal string).
+
+**Add coverage for new behavior:**
+- Wrong-extension rejection now that the regex includes the extension suffix:
+ - `app/translations/en.json` → `getFileType` undefined
+ - `app/graphql/x.txt` → undefined
+ - `app/transactable_types/x.yml.bak` → undefined
+ - `app/authorization_policies/x.txt` → undefined
+- Scalar patterns (from task 2):
+ - `config.yml`, `app/config.yml` → `InstanceConfig`
+ - `user.yml`, `app/user.yml` → `UserType`
+ - `app/asset_manifest.json` → `AssetManifest`
+ - `app/assets.json`, `modules/core/public/assets.json` → `AssetsManifest`
+ - `pos-modules.lock.json`, `app/pos-modules.lock.json`, `pos-module.lock.json` → `ModulesLock`
+- ActivityStreams:
+ - `app/activity_streams/handlers/x.yml` → `ActivityStreamsHandler`
+ - `app/activity_streams/grouping_handlers/x.yml` → `ActivityStreamsGroupingHandler`
+ - Module versions of the same
+- Page/InstanceView with non-`.liquid` extension:
+ - `app/views/pages/home.html` → `getFileType` returns `Page`, `isSupportedSourceFile` returns `false`
+- Asset partials in known dirs:
+ - `app/views/partials/foo.css.liquid` → `isSupportedSourceFile` returns `false`
+ - `app/views/partials/foo.js.liquid` → `isSupportedSourceFile` returns `false`
+- Backend quirks (mirror verbatim, document with comment):
+ - `app/graphqls/x.graphql` → `GraphQL` (the `s?` quirk)
+
+**Existing spec sections to keep/adjust:**
+- `app/ root — *` describes — keep as is
+- `module paths` describe — keep
+- `app/modules nested paths` describe — keep
+- `false positive prevention` describe — keep all cases
+- `getAppPaths` / `getModulePaths` describes — keep
+- Convenience predicates — drop the `marketplace_builder/...` assertions inside them
+
+**Files:**
+- `packages/platformos-common/src/path-utils.spec.ts`
+
+
+## Acceptance Criteria
+
+- [ ] #1 All marketplace_builder/ assertions removed
+- [ ] #2 Scalar-pattern, ActivityStreams, wrong-extension, asset-partial, and Page-non-liquid cases added
+- [ ] #3 yarn workspace @platformos/platformos-common test passes
+
diff --git a/.backlog/tasks/task-6 - Full-build-test-pass-fix-downstream-fallout.md b/.backlog/tasks/task-6 - Full-build-test-pass-fix-downstream-fallout.md
new file mode 100644
index 00000000..635e4a6b
--- /dev/null
+++ b/.backlog/tasks/task-6 - Full-build-test-pass-fix-downstream-fallout.md
@@ -0,0 +1,45 @@
+---
+id: TASK-6
+title: Full build + test pass; fix downstream fallout
+status: To Do
+assignee: []
+created_date: '2026-05-11 13:12'
+labels: []
+dependencies:
+ - TASK-4
+ - TASK-5
+---
+
+## Description
+
+
+After tasks 1–5 land, run the full monorepo build and test suite, and fix any breakage caused by:
+
+- Stricter regex (extension-anchored) classification
+- `marketplace_builder/` removal — any fixture, snapshot, or spec using that root must be migrated to `app/` or deleted
+- `DocumentManager.app()` now filtering graphql/yaml strictly — LSP specs may have fixtures in non-canonical dirs
+
+**Commands:**
+```bash
+NPM_TOKEN=dummy yarn build
+NPM_TOKEN=dummy yarn test
+yarn type-check
+```
+
+**Likely fallout to expect:**
+- `platformos-language-server-common/src/**/*.spec.ts` — fixtures may use `marketplace_builder/` paths
+- `platformos-check-common/src/**/*.spec.ts` — likewise
+- Snapshot mismatches from the URI-classification change
+
+**Files (anticipated, not exhaustive):**
+- Anything that grep `marketplace_builder` still finds under `packages/`
+- Anything that grep `isKnownLiquidFile\|isKnownGraphQLFile\|isKnownYAMLFile` outside path-utils still finds (might be more callers we missed)
+
+
+## Acceptance Criteria
+
+- [ ] #1 yarn build succeeds with zero TypeScript errors
+- [ ] #2 yarn test passes (all 239 test files, 1576+ individual tests)
+- [ ] #3 yarn type-check passes
+- [ ] #4 grep -rn marketplace_builder packages/ --include=*.ts returns no live (non-comment) hits
+
diff --git a/CLAUDE.md b/CLAUDE.md
index 7d792ac5..a27d4ff0 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -151,3 +151,32 @@ export SHOPIFY_TLD_ROOT=/path/to/theme-liquid-docs
theme-docs download
code .
```
+
+
+
+
+
+## BACKLOG WORKFLOW INSTRUCTIONS
+
+This project uses Backlog.md MCP for all task and project management activities.
+
+**CRITICAL GUIDANCE**
+
+- If your client supports MCP resources, read `backlog://workflow/overview` to understand when and how to use Backlog for this project.
+- If your client only supports tools or the above request fails, call `backlog.get_backlog_instructions()` to load the tool-oriented overview. Use the `instruction` selector when you need `task-creation`, `task-execution`, or `task-finalization`.
+
+- **First time working here?** Read the overview resource IMMEDIATELY to learn the workflow
+- **Already familiar?** You should have the overview cached ("## Backlog.md Overview (MCP)")
+- **When to read it**: BEFORE creating tasks, or when you're unsure whether to track work
+
+These guides cover:
+- Decision framework for when to create tasks
+- Search-first workflow to avoid duplicates
+- Links to detailed guides for task creation, execution, and finalization
+- MCP tools reference
+
+You MUST read the overview resource to understand the complete workflow. The information is NOT summarized here.
+
+
+
+
diff --git a/packages/platformos-check-common/src/find-root.ts b/packages/platformos-check-common/src/find-root.ts
index 23640b13..20818c09 100644
--- a/packages/platformos-check-common/src/find-root.ts
+++ b/packages/platformos-check-common/src/find-root.ts
@@ -3,13 +3,28 @@ import * as path from './path';
type FileExists = (uri: string) => Promise;
+function isInsideApp(dir: UriString): boolean {
+ let current = dir;
+ while (true) {
+ const parent = path.dirname(current);
+ if (parent === current) return false;
+ if (path.basename(parent) === 'app') return true;
+ current = parent;
+ }
+}
+
async function isRoot(dir: UriString, fileExists: FileExists) {
return or(
fileExists(path.join(dir, '.pos')),
fileExists(path.join(dir, '.platformos-check.yml')),
fileExists(path.join(dir, 'app')),
- // modules/ is a root indicator only when not inside app/ (app/modules/ is a valid subdirectory)
- and(fileExists(path.join(dir, 'modules')), Promise.resolve(path.basename(dir) !== 'app')),
+ // modules/ is a root indicator only when not inside an app/ subtree.
+ // app/modules/ is a valid subdirectory, and app/views/partials/modules/ is a
+ // legitimate partial organization that should not be mistaken for a project root.
+ and(
+ fileExists(path.join(dir, 'modules')),
+ Promise.resolve(path.basename(dir) !== 'app' && !isInsideApp(dir)),
+ ),
);
}
diff --git a/packages/platformos-check-common/src/index.ts b/packages/platformos-check-common/src/index.ts
index eb9fee4d..38c4bfb2 100644
--- a/packages/platformos-check-common/src/index.ts
+++ b/packages/platformos-check-common/src/index.ts
@@ -60,11 +60,13 @@ export {
isFormConfiguration,
isKnownGraphQLFile,
isKnownLiquidFile,
+ isKnownYAMLFile,
isLayout,
isMigration,
isPage,
isPartial,
isSms,
+ isSupportedSourceFile,
PlatformOSFileType,
} from '@platformos/platformos-common';
export * from './frontmatter';
diff --git a/packages/platformos-check-docs-updater/data/latest.json b/packages/platformos-check-docs-updater/data/latest.json
index 4b059ad2..b90959cb 100644
--- a/packages/platformos-check-docs-updater/data/latest.json
+++ b/packages/platformos-check-docs-updater/data/latest.json
@@ -1,2 +1,2 @@
-{"revision":"05ac4637cfd868fd7f72e2a1ebf40fc93428e114"}
+{"revision":"30103f74fe1f031dc5aec3a8f0608339bd2b858d"}
diff --git a/packages/platformos-check-node/src/find-root.spec.ts b/packages/platformos-check-node/src/find-root.spec.ts
index b2f57799..2b1b36e7 100644
--- a/packages/platformos-check-node/src/find-root.spec.ts
+++ b/packages/platformos-check-node/src/find-root.spec.ts
@@ -124,4 +124,41 @@ describe('Unit: findRoot', () => {
expect(root).toBe(workspace.uri('.'));
});
});
+
+ describe('with partials organized under a modules/ subdirectory', () => {
+ let workspace: Workspace;
+
+ beforeAll(async () => {
+ // Real-world structure: partials grouped by module name under
+ // app/views/partials/modules/. This must NOT be treated as a project root.
+ workspace = await makeTempWorkspace({
+ app: {
+ views: {
+ partials: {
+ modules: {
+ foo: {
+ 'bar.liquid': '',
+ },
+ },
+ baz: {
+ 'qux.liquid': '',
+ },
+ },
+ },
+ },
+ });
+ });
+
+ afterAll(async () => {
+ await workspace.clean();
+ });
+
+ it('walks past app/views/partials/ even when a modules/ subdir exists there', async () => {
+ const root = await findRoot(
+ workspace.uri('app/views/partials/baz/qux.liquid'),
+ fileExists,
+ );
+ expect(root).toBe(workspace.uri('.'));
+ });
+ });
});
diff --git a/packages/platformos-check-node/src/index.spec.ts b/packages/platformos-check-node/src/index.spec.ts
index 2c2e1303..2ed68718 100644
--- a/packages/platformos-check-node/src/index.spec.ts
+++ b/packages/platformos-check-node/src/index.spec.ts
@@ -9,10 +9,10 @@ describe('Unit: getApp', () => {
beforeEach(async () => {
workspace = await makeTempWorkspace({
- locales: {
- 'en.default.json': '{}',
- },
app: {
+ translations: {
+ 'en.yml': 'en:\n hello: Hello',
+ },
views: {
partials: {
'header.liquid': '',
@@ -34,13 +34,13 @@ describe('Unit: getApp', () => {
};
const app = await getApp(config);
- const jsonFile = app.find((sc) => sc.type === SourceCodeType.JSON);
- assert(jsonFile);
+ const yamlFile = app.find((sc) => sc.type === SourceCodeType.YAML);
+ assert(yamlFile);
// internally we expect the path to be normalized
// Use .replace() instead of normalize-path here because this is a URI (file:///...),
// not a filesystem path — normalize-path would collapse the triple slash.
- expect(jsonFile.uri).to.equal(workspace.uri('locales/en.default.json').replace(/\\/g, '/'));
+ expect(yamlFile.uri).to.equal(workspace.uri('app/translations/en.yml').replace(/\\/g, '/'));
});
});
@@ -51,6 +51,6 @@ describe('Unit: getAppFilesPathPattern', () => {
const rootUri = pathToFileURL(__dirname);
const normalizedGlob = getAppFilesPathPattern(rootUri.toString());
- expect(normalizedGlob).to.equal(normalize(__dirname) + '/**/*.{liquid,json,graphql,yml,yaml}');
+ expect(normalizedGlob).to.equal(normalize(__dirname) + '/**/*.{liquid,graphql,yml,yaml}');
});
});
diff --git a/packages/platformos-check-node/src/index.ts b/packages/platformos-check-node/src/index.ts
index 6c188f93..e134a564 100644
--- a/packages/platformos-check-node/src/index.ts
+++ b/packages/platformos-check-node/src/index.ts
@@ -14,6 +14,7 @@ import {
isIgnored,
isKnownLiquidFile,
isKnownGraphQLFile,
+ isKnownYAMLFile,
memo,
path as pathUtils,
YAMLSourceCode,
@@ -149,6 +150,15 @@ export async function getApp(config: Config): Promise {
// Only lint .graphql files that belong to a recognized platformOS GraphQL directory.
// Schema files, generator templates (e.g. ERB .graphql), etc. are excluded.
if (filePath.endsWith('.graphql') && !isKnownGraphQLFile(filePath)) return false;
+ // Only lint .yml/.yaml files that belong to a recognized platformOS YAML
+ // directory (translations, custom model types, etc.). Config files like
+ // config.yml or .platformos-check.yml are excluded.
+ if (
+ (filePath.endsWith('.yml') || filePath.endsWith('.yaml')) &&
+ !isKnownYAMLFile(filePath)
+ ) {
+ return false;
+ }
return true;
}),
);
@@ -160,7 +170,7 @@ export async function getApp(config: Config): Promise {
}
export function getAppFilesPathPattern(rootUri: string) {
- return normalize(path.join(fileURLToPath(rootUri), '**/*.{liquid,json,graphql,yml,yaml}'));
+ return normalize(path.join(fileURLToPath(rootUri), '**/*.{liquid,graphql,yml,yaml}'));
}
/** @deprecated Use appCheckRun instead */
diff --git a/packages/platformos-common/src/path-utils.ts b/packages/platformos-common/src/path-utils.ts
index 6ddf5270..47fc9a09 100644
--- a/packages/platformos-common/src/path-utils.ts
+++ b/packages/platformos-common/src/path-utils.ts
@@ -129,6 +129,16 @@ const LIQUID_FILE_TYPES = new Set([
PlatformOSFileType.FormConfiguration,
]);
+/**
+ * YAML-based file types. Liquid, GraphQL, and Asset types are excluded.
+ */
+const YAML_FILE_TYPES = new Set([
+ PlatformOSFileType.CustomModelType,
+ PlatformOSFileType.InstanceProfileType,
+ PlatformOSFileType.TransactableType,
+ PlatformOSFileType.Translation,
+]);
+
/**
* Pre-compiled regex per file type, derived entirely from FILE_TYPE_DIRS.
*
@@ -242,6 +252,32 @@ export function isKnownGraphQLFile(uri: UriString): boolean {
return getFileType(uri) === PlatformOSFileType.GraphQL;
}
+/**
+ * Returns true if the URI belongs to a recognized platformOS YAML-source
+ * directory (translations, custom model types, profile types, transactable
+ * types). Config files like `config.yml` or `.platformos-check.yml` return
+ * false because they aren't classified by FILE_TYPE_DIRS.
+ */
+export function isKnownYAMLFile(uri: UriString): boolean {
+ const type = getFileType(uri);
+ return type !== undefined && YAML_FILE_TYPES.has(type);
+}
+
+/**
+ * Returns true if the URI is a platformOS source file the LSP and linter
+ * should load and parse: a known Liquid, GraphQL, or YAML source. Standalone
+ * `.json` files are never platformOS sources — JSON is served via
+ * `.json.liquid`, which is classified by its `.liquid` extension. Asset
+ * partials (`.css.liquid`, `.scss.liquid`, `.js.liquid`) are excluded.
+ */
+export function isSupportedSourceFile(uri: UriString): boolean {
+ if (/\.(s?css|js)\.liquid$/.test(uri)) return false;
+ if (uri.endsWith('.liquid')) return isKnownLiquidFile(uri);
+ if (uri.endsWith('.graphql')) return isKnownGraphQLFile(uri);
+ if (uri.endsWith('.yml') || uri.endsWith('.yaml')) return isKnownYAMLFile(uri);
+ return false;
+}
+
export function isPartial(uri: UriString): boolean {
return getFileType(uri) === PlatformOSFileType.Partial;
}
diff --git a/packages/platformos-language-server-common/src/codeActions/providers/FixAllProvider.spec.ts b/packages/platformos-language-server-common/src/codeActions/providers/FixAllProvider.spec.ts
index 160c6962..625c78ab 100644
--- a/packages/platformos-language-server-common/src/codeActions/providers/FixAllProvider.spec.ts
+++ b/packages/platformos-language-server-common/src/codeActions/providers/FixAllProvider.spec.ts
@@ -7,7 +7,7 @@ import { FixAllProvider } from './FixAllProvider';
import { TextDocument } from 'vscode-languageserver-textdocument';
describe('Unit: FixAllProvider', () => {
- const uri = path.normalize(URI.file('/path/to/file.liquid'));
+ const uri = path.normalize(URI.file('/path/to/app/views/partials/file.liquid'));
const contents = `
{% assign x = 1 %}
@@ -31,7 +31,7 @@ describe('Unit: FixAllProvider', () => {
type: SourceCodeType.LiquidHtml,
check: checkName,
message: 'Parser blocking script detected',
- uri: 'file:///path/to/file.liquid',
+ uri,
severity: Severity.ERROR,
start: { ...document.positionAt(start), index: start },
end: { ...document.positionAt(end), index: end },
diff --git a/packages/platformos-language-server-common/src/codeActions/providers/FixProvider.spec.ts b/packages/platformos-language-server-common/src/codeActions/providers/FixProvider.spec.ts
index a325b13f..61c041f0 100644
--- a/packages/platformos-language-server-common/src/codeActions/providers/FixProvider.spec.ts
+++ b/packages/platformos-language-server-common/src/codeActions/providers/FixProvider.spec.ts
@@ -7,7 +7,7 @@ import { FixProvider } from './FixProvider';
import { TextDocument } from 'vscode-languageserver-textdocument';
describe('Unit: FixProvider', () => {
- const uri = path.normalize(URI.file('/path/to/file.liquid'));
+ const uri = path.normalize(URI.file('/path/to/app/views/partials/file.liquid'));
const contents = `
{% assign x = 1 %}
@@ -30,7 +30,7 @@ describe('Unit: FixProvider', () => {
type: SourceCodeType.LiquidHtml,
check: checkName,
message: 'Parser blocking script detected',
- uri: 'file:///path/to/file.liquid',
+ uri,
severity: Severity.ERROR,
start: { ...document.positionAt(start), index: start },
end: { ...document.positionAt(end), index: end },
diff --git a/packages/platformos-language-server-common/src/codeActions/providers/SuggestionProvider.spec.ts b/packages/platformos-language-server-common/src/codeActions/providers/SuggestionProvider.spec.ts
index 4ea56e5e..095fc937 100644
--- a/packages/platformos-language-server-common/src/codeActions/providers/SuggestionProvider.spec.ts
+++ b/packages/platformos-language-server-common/src/codeActions/providers/SuggestionProvider.spec.ts
@@ -13,7 +13,7 @@ import { DocumentManager } from '../../documents';
import { SuggestionProvider } from './SuggestionProvider';
describe('Unit: SuggestionProvider', () => {
- const uri = path.normalize(URI.file('/path/to/file.liquid'));
+ const uri = path.normalize(URI.file('/path/to/app/views/partials/file.liquid'));
const contents = `
{% assign x = 1 %}
@@ -41,7 +41,7 @@ describe('Unit: SuggestionProvider', () => {
type: SourceCodeType.LiquidHtml,
check: checkName,
message: 'Parser blocking script detected',
- uri: 'file:///path/to/file.liquid',
+ uri,
severity: Severity.ERROR,
start: { ...document.positionAt(start), index: start },
end: { ...document.positionAt(end), index: end },
diff --git a/packages/platformos-language-server-common/src/commands/providers/ApplyFixesProvider.spec.ts b/packages/platformos-language-server-common/src/commands/providers/ApplyFixesProvider.spec.ts
index 7d6229fe..6169eecf 100644
--- a/packages/platformos-language-server-common/src/commands/providers/ApplyFixesProvider.spec.ts
+++ b/packages/platformos-language-server-common/src/commands/providers/ApplyFixesProvider.spec.ts
@@ -14,7 +14,7 @@ import { DocumentManager } from '../../documents';
import { ApplyFixesProvider } from './ApplyFixesProvider';
describe('Unit: ApplyFixesProvider', () => {
- const uri = path.normalize(URI.file('/path/to/file.liquid'));
+ const uri = path.normalize(URI.file('/path/to/app/views/partials/file.liquid'));
const contents = `
{% assign x = 1 %}
@@ -38,7 +38,7 @@ describe('Unit: ApplyFixesProvider', () => {
type: SourceCodeType.LiquidHtml,
check: checkName,
message: 'Offense detected',
- uri: 'file:///path/to/file.liquid',
+ uri,
severity: Severity.ERROR,
start: { ...document.positionAt(start), index: start },
end: { ...document.positionAt(end), index: end },
diff --git a/packages/platformos-language-server-common/src/commands/providers/ApplySuggestionProvider.spec.ts b/packages/platformos-language-server-common/src/commands/providers/ApplySuggestionProvider.spec.ts
index 0abdc2e8..ab60ad31 100644
--- a/packages/platformos-language-server-common/src/commands/providers/ApplySuggestionProvider.spec.ts
+++ b/packages/platformos-language-server-common/src/commands/providers/ApplySuggestionProvider.spec.ts
@@ -15,7 +15,7 @@ import { TextDocument } from 'vscode-languageserver-textdocument';
import { offenseToDiagnostic } from '../../diagnostics/offenseToDiagnostic';
describe('Unit: ApplySuggestionProvider', () => {
- const uri = path.normalize(URI.file('/path/to/file.liquid'));
+ const uri = path.normalize(URI.file('/path/to/app/views/partials/file.liquid'));
const contents = `
{% assign x = 1 %}
@@ -44,7 +44,7 @@ describe('Unit: ApplySuggestionProvider', () => {
type: SourceCodeType.LiquidHtml,
check: checkName,
message: 'Parser blocking script detected',
- uri: 'file:///path/to/file.liquid',
+ uri,
severity: Severity.ERROR,
start: { ...document.positionAt(start), index: start },
end: { ...document.positionAt(end), index: end },
diff --git a/packages/platformos-language-server-common/src/commands/providers/RunChecksProvider.spec.ts b/packages/platformos-language-server-common/src/commands/providers/RunChecksProvider.spec.ts
index 759363eb..ee0b9e3d 100644
--- a/packages/platformos-language-server-common/src/commands/providers/RunChecksProvider.spec.ts
+++ b/packages/platformos-language-server-common/src/commands/providers/RunChecksProvider.spec.ts
@@ -9,8 +9,8 @@ import { DebouncedFunction } from '../../utils';
import { RunChecksProvider } from './RunChecksProvider';
describe('Unit: RunChecksProvider', () => {
- const uri1 = path.normalize(URI.file('/path/to/file1.liquid'));
- const uri2 = path.normalize(URI.file('/path/to/file2.liquid'));
+ const uri1 = path.normalize(URI.file('/path/to/app/views/partials/file1.liquid'));
+ const uri2 = path.normalize(URI.file('/path/to/app/views/partials/file2.liquid'));
const contents1 = `
{% assign x = 1 %}
diff --git a/packages/platformos-language-server-common/src/completions/params/LiquidCompletionParams.spec.ts b/packages/platformos-language-server-common/src/completions/params/LiquidCompletionParams.spec.ts
index 816fc2a7..8808e8cc 100644
--- a/packages/platformos-language-server-common/src/completions/params/LiquidCompletionParams.spec.ts
+++ b/packages/platformos-language-server-common/src/completions/params/LiquidCompletionParams.spec.ts
@@ -278,7 +278,7 @@ function createLiquidParamsFromContext(
) {
const regex = new RegExp('█', 'g');
const documentManager = new DocumentManager();
- const uri = 'file:///path/to/file.liquid';
+ const uri = 'file:///app/views/partials/file.liquid';
documentManager.open(uri, context.replace(regex, ''), 1);
const params = mockCompletionParams({ position: cursorPosition });
return createLiquidCompletionParams(
@@ -303,7 +303,7 @@ function mockCompletionParams(params: Partial = {}): Completio
line: 0,
},
textDocument: {
- uri: 'file:///path/to/file.liquid',
+ uri: 'file:///app/views/partials/file.liquid',
},
...params,
};
diff --git a/packages/platformos-language-server-common/src/completions/providers/ObjectCompletionProvider.spec.ts b/packages/platformos-language-server-common/src/completions/providers/ObjectCompletionProvider.spec.ts
index 609c7e55..d61dafae 100644
--- a/packages/platformos-language-server-common/src/completions/providers/ObjectCompletionProvider.spec.ts
+++ b/packages/platformos-language-server-common/src/completions/providers/ObjectCompletionProvider.spec.ts
@@ -133,7 +133,10 @@ describe('Module: ObjectCompletionProvider', async () => {
for (const [object, relativePath] of contexts) {
const source = `{{ ${object}█ }}`;
await expect(provider, source).to.complete({ source, relativePath }, [object]);
- await expect(provider, source).to.complete({ source, relativePath: 'file.liquid' }, []);
+ await expect(provider, source).to.complete(
+ { source, relativePath: 'app/views/layouts/main.liquid' },
+ [],
+ );
}
});
diff --git a/packages/platformos-language-server-common/src/definitions/providers/TranslationStringDefinitionProvider.spec.ts b/packages/platformos-language-server-common/src/definitions/providers/TranslationStringDefinitionProvider.spec.ts
index 2e511129..49676d4b 100644
--- a/packages/platformos-language-server-common/src/definitions/providers/TranslationStringDefinitionProvider.spec.ts
+++ b/packages/platformos-language-server-common/src/definitions/providers/TranslationStringDefinitionProvider.spec.ts
@@ -37,9 +37,9 @@ describe('Module: TranslationStringDefinitionProvider', () => {
});
it('finds the definition of existing translation keys', async () => {
- documentManager.open('file:///test.liquid', '{{ "hello.world" | t }}', 1);
+ documentManager.open('file:///app/views/partials/test.liquid', '{{ "hello.world" | t }}', 1);
const params: DefinitionParams = {
- textDocument: { uri: 'file:///test.liquid' },
+ textDocument: { uri: 'file:///app/views/partials/test.liquid' },
position: { line: 0, character: 5 }, // Position within "hello.world"
};
diff --git a/packages/platformos-language-server-common/src/documentHighlights/providers/HtmlTagNameDocumentHighlightsProvider.spec.ts b/packages/platformos-language-server-common/src/documentHighlights/providers/HtmlTagNameDocumentHighlightsProvider.spec.ts
index ff4c231b..309a8eaf 100644
--- a/packages/platformos-language-server-common/src/documentHighlights/providers/HtmlTagNameDocumentHighlightsProvider.spec.ts
+++ b/packages/platformos-language-server-common/src/documentHighlights/providers/HtmlTagNameDocumentHighlightsProvider.spec.ts
@@ -15,7 +15,7 @@ describe('Module: HtmlTagNameDocumentHighlightsProvider', () => {
it('should return [] for non-existent documents', async () => {
const params: DocumentHighlightParams = {
- textDocument: { uri: 'file:///path/to/non-existent-document.liquid' },
+ textDocument: { uri: 'file:///app/views/partials/non-existent-document.liquid' },
position: Position.create(0, 0),
};
@@ -25,7 +25,7 @@ describe('Module: HtmlTagNameDocumentHighlightsProvider', () => {
it('should return [] for non-HTML documents', async () => {
const params: DocumentHighlightParams = {
- textDocument: { uri: 'file:///path/to/document.liquid' },
+ textDocument: { uri: 'file:///app/views/partials/document.liquid' },
position: Position.create(0, 0),
};
@@ -37,7 +37,7 @@ describe('Module: HtmlTagNameDocumentHighlightsProvider', () => {
it('should return document highlight ranges for HTML tag names', async () => {
const params: DocumentHighlightParams = {
- textDocument: { uri: 'file:///path/to/document.liquid' },
+ textDocument: { uri: 'file:///app/views/partials/document.liquid' },
position: Position.create(0, 3), // position within the tag name
};
@@ -60,7 +60,7 @@ describe('Module: HtmlTagNameDocumentHighlightsProvider', () => {
it('should return document highlight ranges for closing HTML tag names', async () => {
const params: DocumentHighlightParams = {
- textDocument: { uri: 'file:///path/to/document.liquid' },
+ textDocument: { uri: 'file:///app/views/partials/document.liquid' },
position: Position.create(0, 16), // position within the closing div tag name
};
@@ -82,7 +82,7 @@ describe('Module: HtmlTagNameDocumentHighlightsProvider', () => {
it('return [] for positions not within HTML tag names', async () => {
const params: DocumentHighlightParams = {
- textDocument: { uri: 'file:///path/to/document.liquid' },
+ textDocument: { uri: 'file:///app/views/partials/document.liquid' },
position: Position.create(0, 0), // position outside the tag name
};
diff --git a/packages/platformos-language-server-common/src/documentHighlights/providers/LiquidBlockTagDocumentHighlightsProvider.spec.ts b/packages/platformos-language-server-common/src/documentHighlights/providers/LiquidBlockTagDocumentHighlightsProvider.spec.ts
index 5e4c034e..bd0a4c0e 100644
--- a/packages/platformos-language-server-common/src/documentHighlights/providers/LiquidBlockTagDocumentHighlightsProvider.spec.ts
+++ b/packages/platformos-language-server-common/src/documentHighlights/providers/LiquidBlockTagDocumentHighlightsProvider.spec.ts
@@ -15,7 +15,7 @@ describe('Module: LiquidBlockTagDocumentHighlightsProvider', () => {
it('should return document highlight ranges for liquid blocks', async () => {
const params: DocumentHighlightParams = {
- textDocument: { uri: 'file:///path/to/document.liquid' },
+ textDocument: { uri: 'file:///app/views/partials/document.liquid' },
position: Position.create(0, 4), // position within the tag name
};
@@ -38,7 +38,7 @@ describe('Module: LiquidBlockTagDocumentHighlightsProvider', () => {
it('should return document highlight ranges for liquid conditionals', async () => {
const params: DocumentHighlightParams = {
- textDocument: { uri: 'file:///path/to/document.liquid' },
+ textDocument: { uri: 'file:///app/views/partials/document.liquid' },
position: Position.create(0, 4),
};
@@ -70,7 +70,7 @@ describe('Module: LiquidBlockTagDocumentHighlightsProvider', () => {
it('should return document highlight ranges for liquid case statements', async () => {
const params: DocumentHighlightParams = {
- textDocument: { uri: 'file:///path/to/document.liquid' },
+ textDocument: { uri: 'file:///app/views/partials/document.liquid' },
position: Position.create(0, 4),
};
@@ -109,7 +109,7 @@ describe('Module: LiquidBlockTagDocumentHighlightsProvider', () => {
it('should return document highlight ranges for LiquidRawTags tags', async () => {
const params: DocumentHighlightParams = {
- textDocument: { uri: 'file:///path/to/document.liquid' },
+ textDocument: { uri: 'file:///app/views/partials/document.liquid' },
position: Position.create(0, 4),
};
@@ -131,7 +131,7 @@ describe('Module: LiquidBlockTagDocumentHighlightsProvider', () => {
it('should return document highlight ranges for liquid comment tags', async () => {
const params: DocumentHighlightParams = {
- textDocument: { uri: 'file:///path/to/document.liquid' },
+ textDocument: { uri: 'file:///app/views/partials/document.liquid' },
position: Position.create(0, 4),
};
@@ -153,7 +153,7 @@ describe('Module: LiquidBlockTagDocumentHighlightsProvider', () => {
it('should return the correct highlights inside liquid liquid tags', async () => {
const params: DocumentHighlightParams = {
- textDocument: { uri: 'file:///path/to/document.liquid' },
+ textDocument: { uri: 'file:///app/views/partials/document.liquid' },
position: Position.create(1, 10),
};
diff --git a/packages/platformos-language-server-common/src/documentLinks/DocumentLinksProvider.spec.ts b/packages/platformos-language-server-common/src/documentLinks/DocumentLinksProvider.spec.ts
index 597b6dc3..f1aa358e 100644
--- a/packages/platformos-language-server-common/src/documentLinks/DocumentLinksProvider.spec.ts
+++ b/packages/platformos-language-server-common/src/documentLinks/DocumentLinksProvider.spec.ts
@@ -53,7 +53,7 @@ describe('DocumentLinksProvider', () => {
});
it('should return a list of document links with correct URLs for a LiquidHtml document', async () => {
- uriString = 'file:///path/to/liquid-html-document.liquid';
+ uriString = 'file:///app/views/partials/liquid-html-document.liquid';
rootUri = 'file:///path/to/project';
const liquidHtmlContent = `
diff --git a/packages/platformos-language-server-common/src/documents/DocumentManager.ts b/packages/platformos-language-server-common/src/documents/DocumentManager.ts
index 80c85753..ba6a4ab6 100644
--- a/packages/platformos-language-server-common/src/documents/DocumentManager.ts
+++ b/packages/platformos-language-server-common/src/documents/DocumentManager.ts
@@ -1,6 +1,7 @@
import {
assertNever,
isKnownLiquidFile,
+ isSupportedSourceFile,
memoize,
path,
recursiveReadDirectory,
@@ -111,8 +112,7 @@ export class DocumentManager {
private set(uri: UriString, source: string, version: number | undefined) {
uri = path.normalize(uri);
- // We only support json, liquid, graphql, and yaml files.
- if (!/\.(json|liquid|graphql|ya?ml)$/.test(uri) || /\.(s?css|js).liquid$/.test(uri)) {
+ if (!isSupportedSourceFile(uri)) {
return;
}
@@ -139,7 +139,7 @@ export class DocumentManager {
const filesToLoad = await recursiveReadDirectory(
this.fs,
rootUri,
- ([uri]) => /\.(liquid|json|graphql|ya?ml)$/.test(uri) && !this.sourceCodes.has(uri),
+ ([uri]) => isSupportedSourceFile(uri) && !this.sourceCodes.has(uri),
);
progress.report(10, 'Preloading files');
diff --git a/packages/platformos-language-server-common/src/formatting/providers/BracketsAutoclosingOnTypeFormattingProvider.spec.ts b/packages/platformos-language-server-common/src/formatting/providers/BracketsAutoclosingOnTypeFormattingProvider.spec.ts
index df60c896..4d9d03b8 100644
--- a/packages/platformos-language-server-common/src/formatting/providers/BracketsAutoclosingOnTypeFormattingProvider.spec.ts
+++ b/packages/platformos-language-server-common/src/formatting/providers/BracketsAutoclosingOnTypeFormattingProvider.spec.ts
@@ -20,7 +20,7 @@ describe('Module: BracketsAutoclosingOnTypeFormattingProvider', () => {
it('should return a TextEdit to insert a space after "{{" in "{{ }}"', async () => {
const params: DocumentOnTypeFormattingParams = {
- textDocument: { uri: 'file:///path/to/document.liquid' },
+ textDocument: { uri: 'file:///app/views/partials/document.liquid' },
position: Position.create(0, 2),
ch: '{',
options,
@@ -37,7 +37,7 @@ describe('Module: BracketsAutoclosingOnTypeFormattingProvider', () => {
it('should return a TextEdit to insert a space after "{%" in "{% %}"', async () => {
const params: DocumentOnTypeFormattingParams = {
- textDocument: { uri: 'file:///path/to/document.liquid' },
+ textDocument: { uri: 'file:///app/views/partials/document.liquid' },
position: Position.create(0, 2),
ch: '%',
options,
@@ -54,7 +54,7 @@ describe('Module: BracketsAutoclosingOnTypeFormattingProvider', () => {
it('should return a TextEdit to replace and insert characters in "{{ - }}"', async () => {
const params: DocumentOnTypeFormattingParams = {
- textDocument: { uri: 'file:///path/to/document.liquid' },
+ textDocument: { uri: 'file:///app/views/partials/document.liquid' },
position: Position.create(0, 4),
ch: '-',
options,
@@ -71,7 +71,7 @@ describe('Module: BracketsAutoclosingOnTypeFormattingProvider', () => {
it('should return a TextEdit to replace and insert characters in "{% - %}"', async () => {
const params: DocumentOnTypeFormattingParams = {
- textDocument: { uri: 'file:///path/to/document.liquid' },
+ textDocument: { uri: 'file:///app/views/partials/document.liquid' },
position: Position.create(0, 4),
ch: '-',
options,
diff --git a/packages/platformos-language-server-common/src/formatting/providers/HtmlElementAutoclosingOnTypeFormattingProvider.spec.ts b/packages/platformos-language-server-common/src/formatting/providers/HtmlElementAutoclosingOnTypeFormattingProvider.spec.ts
index c288408d..b0f7f2ef 100644
--- a/packages/platformos-language-server-common/src/formatting/providers/HtmlElementAutoclosingOnTypeFormattingProvider.spec.ts
+++ b/packages/platformos-language-server-common/src/formatting/providers/HtmlElementAutoclosingOnTypeFormattingProvider.spec.ts
@@ -13,7 +13,7 @@ describe('Module: HtmlElementAutoclosingOnTypeFormattingProvider', () => {
let documentManager: DocumentManager;
let onTypeFormattingProvider: OnTypeFormattingProvider;
let setCursorPositionSpy: SetCursorPosition;
- const uri = 'file:///path/to/document.liquid';
+ const uri = 'file:///app/views/partials/document.liquid';
beforeEach(() => {
setCursorPositionSpy = vi.fn(async () => {}) as SetCursorPosition;
diff --git a/packages/platformos-language-server-common/src/hover/providers/LiquidObjectHoverProvider.spec.ts b/packages/platformos-language-server-common/src/hover/providers/LiquidObjectHoverProvider.spec.ts
index dcc16f71..f2e3b91d 100644
--- a/packages/platformos-language-server-common/src/hover/providers/LiquidObjectHoverProvider.spec.ts
+++ b/packages/platformos-language-server-common/src/hover/providers/LiquidObjectHoverProvider.spec.ts
@@ -161,7 +161,10 @@ describe('Module: LiquidObjectHoverProvider', async () => {
{ source, relativePath },
expect.stringContaining(`## ${object}`),
);
- await expect(provider).to.hover({ source, relativePath: 'file.liquid' }, null);
+ await expect(provider).to.hover(
+ { source, relativePath: 'app/views/layouts/main.liquid' },
+ null,
+ );
}
});
diff --git a/packages/platformos-language-server-common/src/linkedEditingRanges/providers/EmptyHtmlTagLinkedRangesProvider.spec.ts b/packages/platformos-language-server-common/src/linkedEditingRanges/providers/EmptyHtmlTagLinkedRangesProvider.spec.ts
index fcafdf06..0ab96df0 100644
--- a/packages/platformos-language-server-common/src/linkedEditingRanges/providers/EmptyHtmlTagLinkedRangesProvider.spec.ts
+++ b/packages/platformos-language-server-common/src/linkedEditingRanges/providers/EmptyHtmlTagLinkedRangesProvider.spec.ts
@@ -16,7 +16,7 @@ describe('Module: EmptyHtmlTagLinkedRangesProvider', () => {
it('should return null for non-existent documents', async () => {
const params: LinkedEditingRangeParams = {
- textDocument: { uri: 'file:///path/to/non-existent-document.liquid' },
+ textDocument: { uri: 'file:///app/views/partials/non-existent-document.liquid' },
position: Position.create(0, 0),
};
@@ -26,7 +26,7 @@ describe('Module: EmptyHtmlTagLinkedRangesProvider', () => {
it('should return null for non-empty HTML tags', async () => {
const params: LinkedEditingRangeParams = {
- textDocument: { uri: 'file:///path/to/document.liquid' },
+ textDocument: { uri: 'file:///app/views/partials/document.liquid' },
position: Position.create(0, 0),
};
@@ -38,7 +38,7 @@ describe('Module: EmptyHtmlTagLinkedRangesProvider', () => {
it('should return linked editing ranges for empty HTML tags', async () => {
const params: LinkedEditingRangeParams = {
- textDocument: { uri: 'file:///path/to/document.liquid' },
+ textDocument: { uri: 'file:///app/views/partials/document.liquid' },
position: Position.create(0, 1), // position within the empty tag
};
@@ -62,7 +62,7 @@ describe('Module: EmptyHtmlTagLinkedRangesProvider', () => {
it('should return null for positions not within empty HTML tags', async () => {
const params: LinkedEditingRangeParams = {
- textDocument: { uri: 'file:///path/to/document.liquid' },
+ textDocument: { uri: 'file:///app/views/partials/document.liquid' },
position: Position.create(0, 0), // position outside the tag
};
diff --git a/packages/platformos-language-server-common/src/linkedEditingRanges/providers/HtmlTagNameLinkedRangesProvider.spec.ts b/packages/platformos-language-server-common/src/linkedEditingRanges/providers/HtmlTagNameLinkedRangesProvider.spec.ts
index fc771ef1..0fd261f6 100644
--- a/packages/platformos-language-server-common/src/linkedEditingRanges/providers/HtmlTagNameLinkedRangesProvider.spec.ts
+++ b/packages/platformos-language-server-common/src/linkedEditingRanges/providers/HtmlTagNameLinkedRangesProvider.spec.ts
@@ -7,7 +7,7 @@ import { htmlElementNameWordPattern } from '../wordPattern';
import { TextDocument } from 'vscode-languageserver-textdocument';
describe('Module: HtmlTagNameLinkedRangesProvider', () => {
- const uri = 'file:///path/to/document.liquid';
+ const uri = 'file:///app/views/partials/document.liquid';
let documentManager: DocumentManager;
let provider: LinkedEditingRangesProvider;
let params: LinkedEditingRangeParams;
diff --git a/packages/platformos-language-server-common/src/rename/providers/HtmlTagNameRenameProvider.spec.ts b/packages/platformos-language-server-common/src/rename/providers/HtmlTagNameRenameProvider.spec.ts
index 452b8bcb..b66dba12 100644
--- a/packages/platformos-language-server-common/src/rename/providers/HtmlTagNameRenameProvider.spec.ts
+++ b/packages/platformos-language-server-common/src/rename/providers/HtmlTagNameRenameProvider.spec.ts
@@ -23,7 +23,7 @@ describe('HtmlTagNameRenameProvider', () => {
it('returns null when the cursor is not over an HTML tag name', async () => {
const params = {
- textDocument: { uri: 'file:///path/to/document.liquid' },
+ textDocument: { uri: 'file:///app/views/partials/document.liquid' },
position: Position.create(0, 0),
newName: 'new-name',
};
@@ -34,7 +34,7 @@ describe('HtmlTagNameRenameProvider', () => {
it('returns the correct workspace edit when renaming an HTML tag name', async () => {
const params = {
- textDocument: { uri: 'file:///path/to/document.liquid' },
+ textDocument: { uri: 'file:///app/views/partials/document.liquid' },
position: Position.create(0, 2),
newName: 'new-name',
};
@@ -59,7 +59,7 @@ describe('HtmlTagNameRenameProvider', () => {
it('also works on complext liquid + text html tag names', async () => {
const params = {
- textDocument: { uri: 'file:///path/to/document.liquid' },
+ textDocument: { uri: 'file:///app/views/partials/document.liquid' },
position: Position.create(0, 2),
newName: 'new-name',
};
diff --git a/packages/platformos-language-server-common/src/test/CompletionItemsAssertion.ts b/packages/platformos-language-server-common/src/test/CompletionItemsAssertion.ts
index eed55353..2a874fc1 100644
--- a/packages/platformos-language-server-common/src/test/CompletionItemsAssertion.ts
+++ b/packages/platformos-language-server-common/src/test/CompletionItemsAssertion.ts
@@ -70,7 +70,9 @@ export const complete: RawMatcherFn = async function (
};
function asCompleteContextObject(context: string | CompleteContext): CompleteContext {
- if (typeof context === 'string') return { source: context, relativePath: 'file.liquid' };
+ if (typeof context === 'string') {
+ return { source: context, relativePath: 'app/views/layouts/file.liquid' };
+ }
return context;
}
diff --git a/packages/platformos-language-server-common/src/test/HoverAssertion.ts b/packages/platformos-language-server-common/src/test/HoverAssertion.ts
index 203c7881..bd5908d9 100644
--- a/packages/platformos-language-server-common/src/test/HoverAssertion.ts
+++ b/packages/platformos-language-server-common/src/test/HoverAssertion.ts
@@ -79,6 +79,8 @@ export const hover: RawMatcherFn = async function (
};
function asHoverContext(context: string | HoverContext): HoverContext {
- if (typeof context === 'string') return { source: context, relativePath: 'app/file.liquid' };
+ if (typeof context === 'string') {
+ return { source: context, relativePath: 'app/views/layouts/file.liquid' };
+ }
return context;
}