@starci/eslint-grammar-offset-pop 0.0.0-stage → 0.12.4
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/CHANGELOG.md +10 -0
- package/LICENSE +21 -0
- package/README.md +34 -2
- package/config.mjs +9 -0
- package/index.d.ts +16 -0
- package/index.mjs +11 -0
- package/package.json +55 -4
- package/runtime/engine/plain-object.mjs +5 -0
- package/runtime/engine/runtime-root.mjs +54 -0
- package/runtime/engine/yaml.mjs +161 -0
- package/runtime/knowledge/hfs/canon-pins.yaml +604 -0
- package/runtime/knowledge/hfs/slots.yaml +2552 -0
- package/runtime/scripts/hfs/allows.mjs +57 -0
- package/runtime/scripts/hfs/slots.mjs +259 -0
- package/runtime/scripts/hfs/view.mjs +73 -0
- package/runtime/scripts/lib/glob.mjs +23 -0
- package/runtime/scripts/lib/path-key.mjs +109 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.12.4 - 2026-10-26
|
|
4
|
+
|
|
5
|
+
- Changed: versioned with Grammar 0.12.4; no rule changes beyond the version pin of the exact StarCi family lint dependency.
|
|
6
|
+
|
|
7
|
+
## 0.12.3 - 2026-10-26
|
|
8
|
+
|
|
9
|
+
- Added: the Offset Pop flat config, inheriting Common API checks from the exact matching Grammar lint version without copying implementations.
|
|
10
|
+
- Added: package regression coverage for an inherited status-tone check and mandatory rule attachment.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) StarCi contributors
|
|
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
CHANGED
|
@@ -1,3 +1,35 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @starci/eslint-grammar-offset-pop
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Offset Pop composes the Common renderers and types. This package inherits their checks from the exact matching `@starci/eslint-grammar-starci` release; the rule implementations and shared infrastructure have one owner. Offset Pop has no additional component API rules yet. Its visual choices belong to its DNA and packaged stylesheet.
|
|
4
|
+
|
|
5
|
+
Rule ownership follows `FE-RULE-OWNERSHIP` in `knowledge/patterns/fe/index.yaml`. The family's inheritance is declared in `knowledge/grammars/offset-pop/family.yaml`; the app-shell law is `knowledge/ui/composition/app-shell.yaml`.
|
|
6
|
+
|
|
7
|
+
The managed `fe/eslint.config.mjs` consumes the universal canon and the selected family:
|
|
8
|
+
|
|
9
|
+
```js
|
|
10
|
+
import { loadHfs, starciFeConfig } from "@starci/eslint-canon-fe"
|
|
11
|
+
import { offsetPopGrammarConfig } from "@starci/eslint-grammar-offset-pop"
|
|
12
|
+
|
|
13
|
+
const hfs = loadHfs(import.meta.url)
|
|
14
|
+
export default [...starciFeConfig({ hfs }), ...offsetPopGrammarConfig({ hfs })]
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The inherited rule IDs use the `starci-grammar` prefix. `rules`, `recommended`, `ruleOwners`, `lawOwners`, `ruleDeclarations`, `why` and the default plugin expose the same authoritative objects as the matching Common contract. The package has its own canon pin and generated runtime copy and follows the Grammar version.
|
|
18
|
+
|
|
19
|
+
## Migrating from @starci/eslint-canon-fe 8.x
|
|
20
|
+
|
|
21
|
+
The pinned canon-fe release moved the twenty Grammar component rules (listed in the `@starci/eslint-grammar-starci`
|
|
22
|
+
README and the pinned canon-fe changelog) out of the universal canon. An Offset Pop app receives them
|
|
23
|
+
through this package under the `starci-grammar/` namespace with unchanged IDs, codes and severity.
|
|
24
|
+
|
|
25
|
+
1. Set `sides.fe.grammar` to `offset-pop` in `hfs.json`; no family is inferred.
|
|
26
|
+
2. Install this package at its canon-pins version beside `@starci/eslint-canon-fe` 9 in the app
|
|
27
|
+
root `devDependencies`; it brings the matching `@starci/eslint-grammar-starci`. `starci app check`
|
|
28
|
+
refuses canon-fe 9 without it (`FE_STACK_FAMILY_LINT_MISSING`).
|
|
29
|
+
3. Compose `starciFeConfig({ hfs })` first and `offsetPopGrammarConfig({ hfs })` second (the block
|
|
30
|
+
above); `starci app sync` renders that managed `fe/eslint.config.mjs`.
|
|
31
|
+
4. Rename references to the moved rules from `starci-fe/` to `starci-grammar/`.
|
|
32
|
+
|
|
33
|
+
Consuming apps migrate in their own release.
|
|
34
|
+
|
|
35
|
+
`npm test` runs package regression specs. Grammar and application front ends carry no specs.
|
package/config.mjs
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { starciGrammarConfig } from "@starci/eslint-grammar-starci"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Attach the inherited Common API laws for a front end selecting Offset Pop.
|
|
5
|
+
*
|
|
6
|
+
* @param {{ hfs: object }} input - The front-end HFS view from the universal canon's loadHfs.
|
|
7
|
+
* @returns {Array<object>} Family rules at error under the shared starci-grammar namespace.
|
|
8
|
+
*/
|
|
9
|
+
export const offsetPopGrammarConfig = ({ hfs }) => starciGrammarConfig({ hfs, family: "offset-pop" })
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { starciGrammarConfig } from "@starci/eslint-grammar-starci"
|
|
2
|
+
|
|
3
|
+
export {
|
|
4
|
+
default,
|
|
5
|
+
rules,
|
|
6
|
+
recommended,
|
|
7
|
+
ruleOwners,
|
|
8
|
+
lawOwners,
|
|
9
|
+
ruleDeclarations,
|
|
10
|
+
why,
|
|
11
|
+
} from "@starci/eslint-grammar-starci"
|
|
12
|
+
|
|
13
|
+
/** Attach the inherited Common API checks for the selected Offset Pop family. */
|
|
14
|
+
export declare function offsetPopGrammarConfig(input: {
|
|
15
|
+
hfs: Parameters<typeof starciGrammarConfig>[0]["hfs"]
|
|
16
|
+
}): ReturnType<typeof starciGrammarConfig>
|
package/index.mjs
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Offset Pop inherits the Common component checks from the exact matching Grammar lint release. */
|
|
2
|
+
export {
|
|
3
|
+
default,
|
|
4
|
+
rules,
|
|
5
|
+
recommended,
|
|
6
|
+
ruleOwners,
|
|
7
|
+
lawOwners,
|
|
8
|
+
ruleDeclarations,
|
|
9
|
+
why,
|
|
10
|
+
} from "@starci/eslint-grammar-starci"
|
|
11
|
+
export { offsetPopGrammarConfig } from "./config.mjs"
|
package/package.json
CHANGED
|
@@ -1,6 +1,57 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@starci/eslint-grammar-offset-pop",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.12.4",
|
|
4
|
+
"description": "Offset Pop Grammar lint: the inherited Common component contract over its own visual family.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"private": false,
|
|
8
|
+
"main": "./index.mjs",
|
|
9
|
+
"types": "./index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./index.d.ts",
|
|
13
|
+
"import": "./index.mjs"
|
|
14
|
+
},
|
|
15
|
+
"./package.json": "./package.json"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"LICENSE",
|
|
19
|
+
"*.mjs",
|
|
20
|
+
"*.d.ts",
|
|
21
|
+
"runtime/**",
|
|
22
|
+
"!*.spec.mjs",
|
|
23
|
+
"README.md",
|
|
24
|
+
"CHANGELOG.md"
|
|
25
|
+
],
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=22.13.0"
|
|
28
|
+
},
|
|
29
|
+
"peerDependencies": {
|
|
30
|
+
"eslint": ">=9",
|
|
31
|
+
"typescript": ">=5.9"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@starci/eslint-grammar-starci": "0.12.4"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@typescript-eslint/parser": "8.71.0",
|
|
38
|
+
"eslint": "9.39.5",
|
|
39
|
+
"eslint-plugin-react-hooks": "7.1.1",
|
|
40
|
+
"typescript": "5.9.3"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"prepack": "node ../../hfs/prep-runtime.mjs",
|
|
44
|
+
"pretest": "node ../../hfs/prep-runtime.mjs",
|
|
45
|
+
"test": "node --test \"*.spec.mjs\""
|
|
46
|
+
},
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"access": "public"
|
|
49
|
+
},
|
|
50
|
+
"keywords": [
|
|
51
|
+
"eslint",
|
|
52
|
+
"eslintplugin",
|
|
53
|
+
"starci",
|
|
54
|
+
"grammar",
|
|
55
|
+
"offset-pop"
|
|
56
|
+
]
|
|
57
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// plain-object.mjs — the one "is this a non-array object" predicate the runtime asks with.
|
|
2
|
+
// A leaf beside digest.mjs: schema walkers, config readers and JSON consumers all mean the
|
|
3
|
+
// same thing by "a mapping" - own object, never null, never an array - so they share it here.
|
|
4
|
+
/** True for a non-null, non-array object. Does not check the prototype (a JSON.parse result). */
|
|
5
|
+
export const isPlainObject = (value) => value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import {fileURLToPath} from 'node:url';
|
|
4
|
+
import {parseYaml} from './yaml.mjs';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Runtime root helper. The runtime reads this source tree directly. `skillRoot` is the
|
|
8
|
+
* directory containing `package.json` (this module's parent) — the checkout, or the copy of it
|
|
9
|
+
* an install placed on the host.
|
|
10
|
+
*
|
|
11
|
+
* Every workflow, op, schema, knowledge and model contract read at runtime is an authored YAML
|
|
12
|
+
* file (or an authored JSON one where a document is stored that way). `readModuleJson` resolves a
|
|
13
|
+
* path under `skillRoot` and parses the file by its extension.
|
|
14
|
+
*/
|
|
15
|
+
const moduleRoot = path.dirname(fileURLToPath(new URL('../package.json', import.meta.url)));
|
|
16
|
+
|
|
17
|
+
/** The runtime root: this source tree (or an immutable sealed payload of it). */
|
|
18
|
+
export const skillRoot = moduleRoot;
|
|
19
|
+
/**
|
|
20
|
+
* The StarCi Source root (the host containing .claude and .workspaces): STARCI_SOURCE_ROOT overrides it, else the directory
|
|
21
|
+
* holding this runtime checkout. Parameterized over `env`, so a spec can inject a fixture Source.
|
|
22
|
+
*/
|
|
23
|
+
export const starciSourceRoot = (env = process.env) => (env.STARCI_SOURCE_ROOT ? path.resolve(env.STARCI_SOURCE_ROOT) : path.dirname(skillRoot));
|
|
24
|
+
|
|
25
|
+
/** Overrides the per-host state base wholesale (debug probes, spec trees); the one seam starciLocalRoot reads. */
|
|
26
|
+
export const LOCAL_ROOT_ENV = 'STARCI_LOCAL_ROOT';
|
|
27
|
+
/** The host-data directory of a runtime root. Git-ignored and never packed; the example fixtures under examples/.runtimes are a separate, public exception. */
|
|
28
|
+
export const RUNTIME_STATE_DIR = '.runtime';
|
|
29
|
+
/**
|
|
30
|
+
* <root>/.runtime. The root is the `.claude` of the host Source: the checkout, or the copy `starci runtime install` places at
|
|
31
|
+
* <app>/.claude. ~/.starci/runtime/node_modules/starci is only the CLI's download cache (it supplies the installer and hosts no
|
|
32
|
+
* state), and `starci runtime link` merely points the launcher at a root, so the state follows the code's own location.
|
|
33
|
+
*/
|
|
34
|
+
export const runtimeStateDir = (root = skillRoot) => path.join(root, RUNTIME_STATE_DIR);
|
|
35
|
+
/**
|
|
36
|
+
* The per-host state base, the one owner of every host-state location: machine.sqlite, projects/<ledger_id>/runtime.sqlite, archive/,
|
|
37
|
+
* artifacts/ (the blob store), guards/, host-lock/ and the other process state sit under it. Default <runtime root>/.runtime;
|
|
38
|
+
* LOCAL_ROOT_ENV replaces it wholesale. Nothing is read from or moved out of the earlier %LOCALAPPDATA%/StarCi and ~/.starci locations.
|
|
39
|
+
*/
|
|
40
|
+
export const starciLocalRoot = (env = process.env, root = skillRoot) => (env[LOCAL_ROOT_ENV] ? path.resolve(env[LOCAL_ROOT_ENV]) : runtimeStateDir(root));
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Read a runtime contract document. `parts` are path segments under `skillRoot`
|
|
44
|
+
* (e.g. readModuleJson('modules', 'models', 'kinds.yaml')).
|
|
45
|
+
*/
|
|
46
|
+
export function readModuleJson(...parts) {
|
|
47
|
+
const rel = parts.join('/');
|
|
48
|
+
const file = path.join(skillRoot, rel);
|
|
49
|
+
if (!(file.startsWith(skillRoot) && fs.existsSync(file) && fs.statSync(file).isFile()))
|
|
50
|
+
throw new Error(`Required contract not found for ${rel} under ${skillRoot}`);
|
|
51
|
+
const text = fs.readFileSync(file, 'utf8');
|
|
52
|
+
if (/\.ya?ml$/i.test(file)) return parseYaml(text);
|
|
53
|
+
return JSON.parse(text);
|
|
54
|
+
}
|