@agimon-ai/vibe-lint-plugin-po-core 0.0.0-alpha.10

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 Vuong Ngo
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,3 @@
1
+ # Po core lint rules
2
+
3
+ Use the `po-core/recommended` preset to check package ownership and source layout.
@@ -0,0 +1 @@
1
+ var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,s)=>(s=n==null?{}:e(i(n)),o(r||!n||!n.__esModule||!a.call(n,`default`)?t(s,`default`,{value:n,enumerable:!0}):s,n));exports.__toESM=s;
package/dist/index.cjs ADDED
@@ -0,0 +1,4 @@
1
+ Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("./_virtual/_rolldown/runtime.cjs");let t=require("node:fs");t=e.__toESM(t,1);let n=require("node:path");n=e.__toESM(n,1);let r=require("typescript");r=e.__toESM(r,1);const i=/* @__PURE__ */ new Set([`systems`,`services`,`types`,`schemas`,`models`,`constants`,`extensions`,`pi`,`server`,`web`,`testing`,`exports`]),a=/* @__PURE__ */ new Set([`@agimon-ai/po-core`,`@agimon-ai/po-telemetry`,`@agimon-ai/po-web-security`]),o={preflight:!0,rule:`Keep Po core ownership explicit in folders, imports, and package exports`,rationale:`Core owns reusable runtime logic. CLI builders and composition select and wire features. Feature-specific policies remain in their owning packages.`,check(e,o){if(!t.default.existsSync(e))return null;let s=n.default.relative(o,e).replaceAll(n.default.sep,`/`),c=[];if(s.startsWith(`src/`)&&!i.has(s.split(`/`)[1])&&c.push(`Unsupported source folder: ${s}`),s.startsWith(`src/`)&&/\.[cm]?tsx?$/.test(s)){let n=r.default.createSourceFile(e,t.default.readFileSync(e,`utf8`),r.default.ScriptTarget.Latest,!0),i=e=>{if((r.default.isImportDeclaration(e)||r.default.isExportDeclaration(e))&&e.moduleSpecifier&&r.default.isStringLiteralLike(e.moduleSpecifier)){let t=e.moduleSpecifier.text,n=t.match(/^@agimon-ai\/po(?:-[^/]+)?/)?.[0];n&&!a.has(n)&&c.push(`Downstream dependency: ${n}`),/po-(?:extension-contracts|web-contracts|kernel)(?:\/|$)/.test(t)&&c.push(`Removed package: ${t}`),t.includes(`/src/`)&&c.push(`Import a package capability export: ${t}`)}r.default.forEachChild(e,i)};i(n)}if(s===`package.json`){let n=JSON.parse(t.default.readFileSync(e,`utf8`));for(let e of[`dependencies`,`peerDependencies`,`optionalDependencies`])for(let t of Object.keys(n[e]??{}))t.startsWith(`@agimon-ai/po`)&&!a.has(t)&&c.push(`Downstream dependency: ${t}`)}return c.length?[...new Set(c)].join(`
2
+ `):null}},s=/^po\.[a-z][a-z0-9-]*(?:\.[a-z][a-z0-9-]*)*$/,c={defineDoc:`docs.ts`,defineDocFamily:`docs.ts`,defineEntry:`entries.ts`,defineTask:`tasks.ts`,defineExtension:`extension.ts`,defineTool:`extension.ts`,hook:`extension.ts`,section:`extension.ts`,wrapTool:`extension.ts`,wrapSection:`extension.ts`},l=/^src\/services\/durable[A-Z][A-Za-z0-9]*\/([^/]+)$/;function u(e,t){let[n]=t.arguments;if(!n)return;if(e===`defineEntry`)return r.default.isStringLiteralLike(n)?n.text:void 0;let i=e===`defineExtension`?`name`:[`defineDoc`,`defineDocFamily`,`defineTask`].includes(e)?`kind`:void 0;if(i&&r.default.isObjectLiteralExpression(n)){for(let e of n.properties)if(r.default.isPropertyAssignment(e)&&r.default.isIdentifier(e.name)&&e.name.text===i&&r.default.isStringLiteralLike(e.initializer))return e.initializer.text}}const d={preflight:!0,rule:`Po features built on pi-durable live in src/services/durable<Feature>/, one file per definition kind, with po.* kind names`,rationale:`A kind found in storage or a hook found at runtime should lead to one predictable file. docs.ts holds defineDoc/defineDocFamily, entries.ts defineEntry, tasks.ts defineTask, and extension.ts defineExtension, defineTool, hook, section, wrapTool and wrapSection.`,check(e,i){let a=n.default.relative(i,e).replaceAll(n.default.sep,`/`);if(!a.startsWith(`src/`)||!/\.[cm]?tsx?$/.test(a)||!t.default.existsSync(e))return null;let o=r.default.createSourceFile(e,t.default.readFileSync(e,`utf8`),r.default.ScriptTarget.Latest,!0),d=/* @__PURE__ */ new Map;for(let e of o.statements){if(!r.default.isImportDeclaration(e)||!r.default.isStringLiteralLike(e.moduleSpecifier)||e.moduleSpecifier.text!==`@earendil-works/pi-durable`||e.importClause?.isTypeOnly)continue;let t=e.importClause?.namedBindings;if(t&&r.default.isNamedImports(t))for(let e of t.elements){let t=(e.propertyName??e.name).text;!e.isTypeOnly&&c[t]&&d.set(e.name.text,t)}}if(!d.size)return null;let f=a.match(l)?.[1],p=[],m=e=>{let t=r.default.isCallExpression(e)&&r.default.isIdentifier(e.expression)?d.get(e.expression.text):void 0;if(t&&r.default.isCallExpression(e)){let n=c[t];f!==n&&(n!==`extension.ts`||a!==`src/server/directHarnessRuntime.ts`)&&p.push(`${t} belongs in src/services/durable<Feature>/${n}`);let r=u(t,e);r!==void 0&&!s.test(r)&&p.push(`Kind "${r}" must be po.<feature>[.<name>]: lowercase, dot-separated, never pi.*`)}r.default.forEachChild(e,m)};return m(o),p.length?[...new Set(p)].join(`
3
+ `):null}},f={name:`po-core`,rules:{"po-core-architecture":o,"po-core-durable-features":d},patterns:{ownership:{description:o.rule,includes:[`src/**/*.ts`,`package.json`]},"durable-features":{description:d.rule,includes:[`src/services/durable*/**/*.ts`]}},configs:{recommended:{rules:{"po-core-architecture":`error`,"po-core-durable-features":`error`}}}};exports.architecture=o,exports.default=f,exports.durableFeatures=d;
4
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":["fs","path","ts","require_runtime","node_fs","node_path","typescript","folders","runtimeDependencies","architecture","filePath","relative","configRoot","problems","source","visit","node","reference","dependency","manifest","section","KIND","DEFINITION_FILES","DURABLE_FILE","declaredKind","first","call","definition","key","property","durableFeatures","imported","statement","bindings","element","name","home","file","kind","plugin"],"sources":["../src/index.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport type { RuleDefinition, VibeLintPlugin } from '@agimon-ai/vibe-lint';\nimport ts from 'typescript';\nconst folders = new Set([\n 'systems',\n 'services',\n 'types',\n 'schemas',\n 'models',\n 'constants',\n 'extensions',\n 'pi',\n 'server',\n 'web',\n 'testing',\n 'exports',\n]);\nconst runtimeDependencies = new Set(['@agimon-ai/po-core', '@agimon-ai/po-telemetry', '@agimon-ai/po-web-security']);\nexport const architecture: RuleDefinition = {\n preflight: true,\n rule: 'Keep Po core ownership explicit in folders, imports, and package exports',\n rationale:\n 'Core owns reusable runtime logic. CLI builders and composition select and wire features. Feature-specific policies remain in their owning packages.',\n check(filePath, configRoot) {\n if (!fs.existsSync(filePath)) return null;\n const relative = path.relative(configRoot, filePath).replaceAll(path.sep, '/');\n const problems: string[] = [];\n if (relative.startsWith('src/') && !folders.has(relative.split('/')[1]!))\n problems.push(`Unsupported source folder: ${relative}`);\n if (relative.startsWith('src/') && /\\.[cm]?tsx?$/.test(relative)) {\n const source = ts.createSourceFile(filePath, fs.readFileSync(filePath, 'utf8'), ts.ScriptTarget.Latest, true);\n const visit = (node: ts.Node): void => {\n if (\n (ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) &&\n node.moduleSpecifier &&\n ts.isStringLiteralLike(node.moduleSpecifier)\n ) {\n const reference = node.moduleSpecifier.text;\n const dependency = reference.match(/^@agimon-ai\\/po(?:-[^/]+)?/)?.[0];\n if (dependency && !runtimeDependencies.has(dependency)) problems.push(`Downstream dependency: ${dependency}`);\n if (/po-(?:extension-contracts|web-contracts|kernel)(?:\\/|$)/.test(reference))\n problems.push(`Removed package: ${reference}`);\n if (reference.includes('/src/')) problems.push(`Import a package capability export: ${reference}`);\n }\n ts.forEachChild(node, visit);\n };\n visit(source);\n }\n if (relative === 'package.json') {\n const manifest = JSON.parse(fs.readFileSync(filePath, 'utf8')) as Record<string, unknown>;\n for (const section of ['dependencies', 'peerDependencies', 'optionalDependencies'])\n for (const dependency of Object.keys((manifest[section] ?? {}) as object))\n if (dependency.startsWith('@agimon-ai/po') && !runtimeDependencies.has(dependency))\n problems.push(`Downstream dependency: ${dependency}`);\n }\n return problems.length ? [...new Set(problems)].join('\\n') : null;\n },\n};\n\nconst DURABLE_PACKAGE = '@earendil-works/pi-durable';\n/** Lowercase dotted segments under `po.`; pi-durable reserves `pi.` for its own kinds. */\nconst KIND = /^po\\.[a-z][a-z0-9-]*(?:\\.[a-z][a-z0-9-]*)*$/;\n/** The one file inside a `src/services/durable<Feature>/` folder that may hold each pi-durable definition. */\nconst DEFINITION_FILES: Readonly<Record<string, string>> = {\n defineDoc: 'docs.ts',\n defineDocFamily: 'docs.ts',\n defineEntry: 'entries.ts',\n defineTask: 'tasks.ts',\n defineExtension: 'extension.ts',\n defineTool: 'extension.ts',\n hook: 'extension.ts',\n section: 'extension.ts',\n wrapTool: 'extension.ts',\n wrapSection: 'extension.ts',\n};\n/** The Harness composition installs Po's own hooks inline; every other extension piece has a feature folder. */\nconst HARNESS_COMPOSITION = 'src/server/directHarnessRuntime.ts';\nconst DURABLE_FILE = /^src\\/services\\/durable[A-Z][A-Za-z0-9]*\\/([^/]+)$/;\n\n/** The literal kind (or extension name) a definition call declares, when it is written inline. */\nfunction declaredKind(definition: string, call: ts.CallExpression): string | undefined {\n const [first] = call.arguments;\n if (!first) return undefined;\n if (definition === 'defineEntry') return ts.isStringLiteralLike(first) ? first.text : undefined;\n const key =\n definition === 'defineExtension'\n ? 'name'\n : ['defineDoc', 'defineDocFamily', 'defineTask'].includes(definition)\n ? 'kind'\n : undefined;\n if (!key || !ts.isObjectLiteralExpression(first)) return undefined;\n for (const property of first.properties)\n if (\n ts.isPropertyAssignment(property) &&\n ts.isIdentifier(property.name) &&\n property.name.text === key &&\n ts.isStringLiteralLike(property.initializer)\n )\n return property.initializer.text;\n return undefined;\n}\n\nexport const durableFeatures: RuleDefinition = {\n preflight: true,\n rule: 'Po features built on pi-durable live in src/services/durable<Feature>/, one file per definition kind, with po.* kind names',\n rationale:\n 'A kind found in storage or a hook found at runtime should lead to one predictable file. docs.ts holds defineDoc/defineDocFamily, entries.ts defineEntry, tasks.ts defineTask, and extension.ts defineExtension, defineTool, hook, section, wrapTool and wrapSection.',\n check(filePath, configRoot) {\n const relative = path.relative(configRoot, filePath).replaceAll(path.sep, '/');\n if (!relative.startsWith('src/') || !/\\.[cm]?tsx?$/.test(relative) || !fs.existsSync(filePath)) return null;\n const source = ts.createSourceFile(filePath, fs.readFileSync(filePath, 'utf8'), ts.ScriptTarget.Latest, true);\n // Local name to pi-durable export name, for value imports of the definition helpers only.\n const imported = new Map<string, string>();\n for (const statement of source.statements) {\n if (\n !ts.isImportDeclaration(statement) ||\n !ts.isStringLiteralLike(statement.moduleSpecifier) ||\n statement.moduleSpecifier.text !== DURABLE_PACKAGE ||\n statement.importClause?.isTypeOnly\n )\n continue;\n const bindings = statement.importClause?.namedBindings;\n if (bindings && ts.isNamedImports(bindings))\n for (const element of bindings.elements) {\n const name = (element.propertyName ?? element.name).text;\n if (!element.isTypeOnly && DEFINITION_FILES[name]) imported.set(element.name.text, name);\n }\n }\n if (!imported.size) return null;\n const home = relative.match(DURABLE_FILE)?.[1];\n const problems: string[] = [];\n const visit = (node: ts.Node): void => {\n const definition =\n ts.isCallExpression(node) && ts.isIdentifier(node.expression) ? imported.get(node.expression.text) : undefined;\n if (definition && ts.isCallExpression(node)) {\n const file = DEFINITION_FILES[definition]!;\n if (home !== file && !(file === 'extension.ts' && relative === HARNESS_COMPOSITION))\n problems.push(`${definition} belongs in src/services/durable<Feature>/${file}`);\n const kind = declaredKind(definition, node);\n if (kind !== undefined && !KIND.test(kind))\n problems.push(`Kind \"${kind}\" must be po.<feature>[.<name>]: lowercase, dot-separated, never pi.*`);\n }\n ts.forEachChild(node, visit);\n };\n visit(source);\n return problems.length ? [...new Set(problems)].join('\\n') : null;\n },\n};\n\nconst plugin: VibeLintPlugin = {\n name: 'po-core',\n rules: { 'po-core-architecture': architecture, 'po-core-durable-features': durableFeatures },\n patterns: {\n ownership: { description: architecture.rule, includes: ['src/**/*.ts', 'package.json'] },\n 'durable-features': { description: durableFeatures.rule, includes: ['src/services/durable*/**/*.ts'] },\n },\n configs: { recommended: { rules: { 'po-core-architecture': 'error', 'po-core-durable-features': 'error' } } },\n};\nexport default plugin;\n"],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { RuleDefinition, VibeLintPlugin } from "@agimon-ai/vibe-lint";
2
+ //#region src/index.d.ts
3
+ export declare const architecture: RuleDefinition;
4
+ export declare const durableFeatures: RuleDefinition;
5
+ declare const plugin: VibeLintPlugin;
6
+ //#endregion
7
+ export { plugin as default };
8
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;qBAoBa,cAAc;qBAoFd,iBAAiB;cA+CxB,QAAQ"}
package/dist/index.mjs ADDED
@@ -0,0 +1,4 @@
1
+ import e from"node:fs";import t from"node:path";import n from"typescript";const r=/* @__PURE__ */ new Set([`systems`,`services`,`types`,`schemas`,`models`,`constants`,`extensions`,`pi`,`server`,`web`,`testing`,`exports`]),i=/* @__PURE__ */ new Set([`@agimon-ai/po-core`,`@agimon-ai/po-telemetry`,`@agimon-ai/po-web-security`]),a={preflight:!0,rule:`Keep Po core ownership explicit in folders, imports, and package exports`,rationale:`Core owns reusable runtime logic. CLI builders and composition select and wire features. Feature-specific policies remain in their owning packages.`,check(a,o){if(!e.existsSync(a))return null;let s=t.relative(o,a).replaceAll(t.sep,`/`),c=[];if(s.startsWith(`src/`)&&!r.has(s.split(`/`)[1])&&c.push(`Unsupported source folder: ${s}`),s.startsWith(`src/`)&&/\.[cm]?tsx?$/.test(s)){let t=n.createSourceFile(a,e.readFileSync(a,`utf8`),n.ScriptTarget.Latest,!0),r=e=>{if((n.isImportDeclaration(e)||n.isExportDeclaration(e))&&e.moduleSpecifier&&n.isStringLiteralLike(e.moduleSpecifier)){let t=e.moduleSpecifier.text,n=t.match(/^@agimon-ai\/po(?:-[^/]+)?/)?.[0];n&&!i.has(n)&&c.push(`Downstream dependency: ${n}`),/po-(?:extension-contracts|web-contracts|kernel)(?:\/|$)/.test(t)&&c.push(`Removed package: ${t}`),t.includes(`/src/`)&&c.push(`Import a package capability export: ${t}`)}n.forEachChild(e,r)};r(t)}if(s===`package.json`){let t=JSON.parse(e.readFileSync(a,`utf8`));for(let e of[`dependencies`,`peerDependencies`,`optionalDependencies`])for(let n of Object.keys(t[e]??{}))n.startsWith(`@agimon-ai/po`)&&!i.has(n)&&c.push(`Downstream dependency: ${n}`)}return c.length?[...new Set(c)].join(`
2
+ `):null}},o=/^po\.[a-z][a-z0-9-]*(?:\.[a-z][a-z0-9-]*)*$/,s={defineDoc:`docs.ts`,defineDocFamily:`docs.ts`,defineEntry:`entries.ts`,defineTask:`tasks.ts`,defineExtension:`extension.ts`,defineTool:`extension.ts`,hook:`extension.ts`,section:`extension.ts`,wrapTool:`extension.ts`,wrapSection:`extension.ts`},c=/^src\/services\/durable[A-Z][A-Za-z0-9]*\/([^/]+)$/;function l(e,t){let[r]=t.arguments;if(!r)return;if(e===`defineEntry`)return n.isStringLiteralLike(r)?r.text:void 0;let i=e===`defineExtension`?`name`:[`defineDoc`,`defineDocFamily`,`defineTask`].includes(e)?`kind`:void 0;if(i&&n.isObjectLiteralExpression(r)){for(let e of r.properties)if(n.isPropertyAssignment(e)&&n.isIdentifier(e.name)&&e.name.text===i&&n.isStringLiteralLike(e.initializer))return e.initializer.text}}const u={preflight:!0,rule:`Po features built on pi-durable live in src/services/durable<Feature>/, one file per definition kind, with po.* kind names`,rationale:`A kind found in storage or a hook found at runtime should lead to one predictable file. docs.ts holds defineDoc/defineDocFamily, entries.ts defineEntry, tasks.ts defineTask, and extension.ts defineExtension, defineTool, hook, section, wrapTool and wrapSection.`,check(r,i){let a=t.relative(i,r).replaceAll(t.sep,`/`);if(!a.startsWith(`src/`)||!/\.[cm]?tsx?$/.test(a)||!e.existsSync(r))return null;let u=n.createSourceFile(r,e.readFileSync(r,`utf8`),n.ScriptTarget.Latest,!0),d=/* @__PURE__ */ new Map;for(let e of u.statements){if(!n.isImportDeclaration(e)||!n.isStringLiteralLike(e.moduleSpecifier)||e.moduleSpecifier.text!==`@earendil-works/pi-durable`||e.importClause?.isTypeOnly)continue;let t=e.importClause?.namedBindings;if(t&&n.isNamedImports(t))for(let e of t.elements){let t=(e.propertyName??e.name).text;!e.isTypeOnly&&s[t]&&d.set(e.name.text,t)}}if(!d.size)return null;let f=a.match(c)?.[1],p=[],m=e=>{let t=n.isCallExpression(e)&&n.isIdentifier(e.expression)?d.get(e.expression.text):void 0;if(t&&n.isCallExpression(e)){let n=s[t];f!==n&&(n!==`extension.ts`||a!==`src/server/directHarnessRuntime.ts`)&&p.push(`${t} belongs in src/services/durable<Feature>/${n}`);let r=l(t,e);r!==void 0&&!o.test(r)&&p.push(`Kind "${r}" must be po.<feature>[.<name>]: lowercase, dot-separated, never pi.*`)}n.forEachChild(e,m)};return m(u),p.length?[...new Set(p)].join(`
3
+ `):null}},d={name:`po-core`,rules:{"po-core-architecture":a,"po-core-durable-features":u},patterns:{ownership:{description:a.rule,includes:[`src/**/*.ts`,`package.json`]},"durable-features":{description:u.rule,includes:[`src/services/durable*/**/*.ts`]}},configs:{recommended:{rules:{"po-core-architecture":`error`,"po-core-durable-features":`error`}}}};export{a as architecture,d as default,u as durableFeatures};
4
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["fs","path","ts","folders","runtimeDependencies","architecture","filePath","relative","configRoot","problems","source","visit","node","reference","dependency","manifest","section","KIND","DEFINITION_FILES","DURABLE_FILE","declaredKind","first","call","definition","key","property","durableFeatures","imported","statement","bindings","element","name","home","file","kind","plugin"],"sources":["../src/index.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport type { RuleDefinition, VibeLintPlugin } from '@agimon-ai/vibe-lint';\nimport ts from 'typescript';\nconst folders = new Set([\n 'systems',\n 'services',\n 'types',\n 'schemas',\n 'models',\n 'constants',\n 'extensions',\n 'pi',\n 'server',\n 'web',\n 'testing',\n 'exports',\n]);\nconst runtimeDependencies = new Set(['@agimon-ai/po-core', '@agimon-ai/po-telemetry', '@agimon-ai/po-web-security']);\nexport const architecture: RuleDefinition = {\n preflight: true,\n rule: 'Keep Po core ownership explicit in folders, imports, and package exports',\n rationale:\n 'Core owns reusable runtime logic. CLI builders and composition select and wire features. Feature-specific policies remain in their owning packages.',\n check(filePath, configRoot) {\n if (!fs.existsSync(filePath)) return null;\n const relative = path.relative(configRoot, filePath).replaceAll(path.sep, '/');\n const problems: string[] = [];\n if (relative.startsWith('src/') && !folders.has(relative.split('/')[1]!))\n problems.push(`Unsupported source folder: ${relative}`);\n if (relative.startsWith('src/') && /\\.[cm]?tsx?$/.test(relative)) {\n const source = ts.createSourceFile(filePath, fs.readFileSync(filePath, 'utf8'), ts.ScriptTarget.Latest, true);\n const visit = (node: ts.Node): void => {\n if (\n (ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) &&\n node.moduleSpecifier &&\n ts.isStringLiteralLike(node.moduleSpecifier)\n ) {\n const reference = node.moduleSpecifier.text;\n const dependency = reference.match(/^@agimon-ai\\/po(?:-[^/]+)?/)?.[0];\n if (dependency && !runtimeDependencies.has(dependency)) problems.push(`Downstream dependency: ${dependency}`);\n if (/po-(?:extension-contracts|web-contracts|kernel)(?:\\/|$)/.test(reference))\n problems.push(`Removed package: ${reference}`);\n if (reference.includes('/src/')) problems.push(`Import a package capability export: ${reference}`);\n }\n ts.forEachChild(node, visit);\n };\n visit(source);\n }\n if (relative === 'package.json') {\n const manifest = JSON.parse(fs.readFileSync(filePath, 'utf8')) as Record<string, unknown>;\n for (const section of ['dependencies', 'peerDependencies', 'optionalDependencies'])\n for (const dependency of Object.keys((manifest[section] ?? {}) as object))\n if (dependency.startsWith('@agimon-ai/po') && !runtimeDependencies.has(dependency))\n problems.push(`Downstream dependency: ${dependency}`);\n }\n return problems.length ? [...new Set(problems)].join('\\n') : null;\n },\n};\n\nconst DURABLE_PACKAGE = '@earendil-works/pi-durable';\n/** Lowercase dotted segments under `po.`; pi-durable reserves `pi.` for its own kinds. */\nconst KIND = /^po\\.[a-z][a-z0-9-]*(?:\\.[a-z][a-z0-9-]*)*$/;\n/** The one file inside a `src/services/durable<Feature>/` folder that may hold each pi-durable definition. */\nconst DEFINITION_FILES: Readonly<Record<string, string>> = {\n defineDoc: 'docs.ts',\n defineDocFamily: 'docs.ts',\n defineEntry: 'entries.ts',\n defineTask: 'tasks.ts',\n defineExtension: 'extension.ts',\n defineTool: 'extension.ts',\n hook: 'extension.ts',\n section: 'extension.ts',\n wrapTool: 'extension.ts',\n wrapSection: 'extension.ts',\n};\n/** The Harness composition installs Po's own hooks inline; every other extension piece has a feature folder. */\nconst HARNESS_COMPOSITION = 'src/server/directHarnessRuntime.ts';\nconst DURABLE_FILE = /^src\\/services\\/durable[A-Z][A-Za-z0-9]*\\/([^/]+)$/;\n\n/** The literal kind (or extension name) a definition call declares, when it is written inline. */\nfunction declaredKind(definition: string, call: ts.CallExpression): string | undefined {\n const [first] = call.arguments;\n if (!first) return undefined;\n if (definition === 'defineEntry') return ts.isStringLiteralLike(first) ? first.text : undefined;\n const key =\n definition === 'defineExtension'\n ? 'name'\n : ['defineDoc', 'defineDocFamily', 'defineTask'].includes(definition)\n ? 'kind'\n : undefined;\n if (!key || !ts.isObjectLiteralExpression(first)) return undefined;\n for (const property of first.properties)\n if (\n ts.isPropertyAssignment(property) &&\n ts.isIdentifier(property.name) &&\n property.name.text === key &&\n ts.isStringLiteralLike(property.initializer)\n )\n return property.initializer.text;\n return undefined;\n}\n\nexport const durableFeatures: RuleDefinition = {\n preflight: true,\n rule: 'Po features built on pi-durable live in src/services/durable<Feature>/, one file per definition kind, with po.* kind names',\n rationale:\n 'A kind found in storage or a hook found at runtime should lead to one predictable file. docs.ts holds defineDoc/defineDocFamily, entries.ts defineEntry, tasks.ts defineTask, and extension.ts defineExtension, defineTool, hook, section, wrapTool and wrapSection.',\n check(filePath, configRoot) {\n const relative = path.relative(configRoot, filePath).replaceAll(path.sep, '/');\n if (!relative.startsWith('src/') || !/\\.[cm]?tsx?$/.test(relative) || !fs.existsSync(filePath)) return null;\n const source = ts.createSourceFile(filePath, fs.readFileSync(filePath, 'utf8'), ts.ScriptTarget.Latest, true);\n // Local name to pi-durable export name, for value imports of the definition helpers only.\n const imported = new Map<string, string>();\n for (const statement of source.statements) {\n if (\n !ts.isImportDeclaration(statement) ||\n !ts.isStringLiteralLike(statement.moduleSpecifier) ||\n statement.moduleSpecifier.text !== DURABLE_PACKAGE ||\n statement.importClause?.isTypeOnly\n )\n continue;\n const bindings = statement.importClause?.namedBindings;\n if (bindings && ts.isNamedImports(bindings))\n for (const element of bindings.elements) {\n const name = (element.propertyName ?? element.name).text;\n if (!element.isTypeOnly && DEFINITION_FILES[name]) imported.set(element.name.text, name);\n }\n }\n if (!imported.size) return null;\n const home = relative.match(DURABLE_FILE)?.[1];\n const problems: string[] = [];\n const visit = (node: ts.Node): void => {\n const definition =\n ts.isCallExpression(node) && ts.isIdentifier(node.expression) ? imported.get(node.expression.text) : undefined;\n if (definition && ts.isCallExpression(node)) {\n const file = DEFINITION_FILES[definition]!;\n if (home !== file && !(file === 'extension.ts' && relative === HARNESS_COMPOSITION))\n problems.push(`${definition} belongs in src/services/durable<Feature>/${file}`);\n const kind = declaredKind(definition, node);\n if (kind !== undefined && !KIND.test(kind))\n problems.push(`Kind \"${kind}\" must be po.<feature>[.<name>]: lowercase, dot-separated, never pi.*`);\n }\n ts.forEachChild(node, visit);\n };\n visit(source);\n return problems.length ? [...new Set(problems)].join('\\n') : null;\n },\n};\n\nconst plugin: VibeLintPlugin = {\n name: 'po-core',\n rules: { 'po-core-architecture': architecture, 'po-core-durable-features': durableFeatures },\n patterns: {\n ownership: { description: architecture.rule, includes: ['src/**/*.ts', 'package.json'] },\n 'durable-features': { description: durableFeatures.rule, includes: ['src/services/durable*/**/*.ts'] },\n },\n configs: { recommended: { rules: { 'po-core-architecture': 'error', 'po-core-durable-features': 'error' } } },\n};\nexport default plugin;\n"],"mappings":"0EAKA,MAAMG,kBAAU,IAAI,IAAI,CACtB,UACA,WACA,QACA,UACA,SACA,YACA,aACA,KACA,SACA,MACA,UACA,SACF,CAAC,EACKC,kBAAsB,IAAI,IAAI,CAAC,qBAAsB,0BAA2B,4BAA4B,CAAC,EACtGC,EAA+B,CAC1C,UAAW,GACX,KAAM,2EACN,UACE,sJACF,MAAM,EAAU,EAAY,CAC1B,GAAI,CAACL,EAAG,WAAWM,CAAQ,EAAG,OAAO,KACrC,IAAMC,EAAWN,EAAK,SAASO,EAAYF,CAAQ,CAAC,CAAC,WAAWL,EAAK,IAAK,GAAG,EACvEQ,EAAqB,CAAC,EAG5B,GAFIF,EAAS,WAAW,MAAM,GAAK,CAACJ,EAAQ,IAAII,EAAS,MAAM,GAAG,CAAC,CAAC,EAAG,GACrEE,EAAS,KAAK,8BAA8BF,GAAU,EACpDA,EAAS,WAAW,MAAM,GAAK,eAAe,KAAKA,CAAQ,EAAG,CAChE,IAAMG,EAASR,EAAG,iBAAiBI,EAAUN,EAAG,aAAaM,EAAU,MAAM,EAAGJ,EAAG,aAAa,OAAQ,EAAI,EACtGS,EAAS,GAAwB,CACrC,IACGT,EAAG,oBAAoBU,CAAI,GAAKV,EAAG,oBAAoBU,CAAI,IAC5DA,EAAK,iBACLV,EAAG,oBAAoBU,EAAK,eAAe,EAC3C,CACA,IAAMC,EAAYD,EAAK,gBAAgB,KACjCE,EAAaD,EAAU,MAAM,4BAA4B,CAAC,GAAG,GAC/DC,GAAc,CAACV,EAAoB,IAAIU,CAAU,GAAGL,EAAS,KAAK,0BAA0BK,GAAY,EACxG,0DAA0D,KAAKD,CAAS,GAC1EJ,EAAS,KAAK,oBAAoBI,GAAW,EAC3CA,EAAU,SAAS,OAAO,GAAGJ,EAAS,KAAK,uCAAuCI,GAAW,CACnG,CACAX,EAAG,aAAaU,EAAMD,CAAK,CAC7B,EACAA,EAAMD,CAAM,CACd,CACA,GAAIH,IAAa,eAAgB,CAC/B,IAAMQ,EAAW,KAAK,MAAMf,EAAG,aAAaM,EAAU,MAAM,CAAC,EAC7D,IAAK,IAAMU,IAAW,CAAC,eAAgB,mBAAoB,sBAAsB,EAC/E,IAAK,IAAMF,KAAc,OAAO,KAAMC,EAASC,IAAY,CAAC,CAAY,EAClEF,EAAW,WAAW,eAAe,GAAK,CAACV,EAAoB,IAAIU,CAAU,GAC/EL,EAAS,KAAK,0BAA0BK,GAAY,CAC5D,CACA,OAAOL,EAAS,OAAS,CAAC,GAAG,IAAI,IAAIA,CAAQ,CAAC,CAAC,CAAC,KAAK;CAAI,EAAI,IAC/D,CACF,EAIMQ,EAAO,8CAEPC,EAAqD,CACzD,UAAW,UACX,gBAAiB,UACjB,YAAa,aACb,WAAY,WACZ,gBAAiB,eACjB,WAAY,eACZ,KAAM,eACN,QAAS,eACT,SAAU,eACV,YAAa,cACf,EAGMC,EAAe,qDAGrB,SAASC,EAAa,EAAoB,EAA6C,CACrF,GAAM,CAACC,GAASC,EAAK,UACrB,GAAI,CAACD,EAAO,OACZ,GAAIE,IAAe,cAAe,OAAOrB,EAAG,oBAAoBmB,CAAK,EAAIA,EAAM,KAAO,IAAA,GACtF,IAAMG,EACJD,IAAe,kBACX,OACA,CAAC,YAAa,kBAAmB,YAAY,CAAC,CAAC,SAASA,CAAU,EAChE,OACA,IAAA,GACR,GAAKC,GAAQtB,EAAG,0BAA0BmB,CAAK,EAC/C,KAAK,IAAMI,KAAYJ,EAAM,WAC3B,GACEnB,EAAG,qBAAqBuB,CAAQ,GAChCvB,EAAG,aAAauB,EAAS,IAAI,GAC7BA,EAAS,KAAK,OAASD,GACvBtB,EAAG,oBAAoBuB,EAAS,WAAW,EAE3C,OAAOA,EAAS,YAAY,IAAA,CAElC,CAEA,MAAaC,EAAkC,CAC7C,UAAW,GACX,KAAM,6HACN,UACE,uQACF,MAAM,EAAU,EAAY,CAC1B,IAAMnB,EAAWN,EAAK,SAASO,EAAYF,CAAQ,CAAC,CAAC,WAAWL,EAAK,IAAK,GAAG,EAC7E,GAAI,CAACM,EAAS,WAAW,MAAM,GAAK,CAAC,eAAe,KAAKA,CAAQ,GAAK,CAACP,EAAG,WAAWM,CAAQ,EAAG,OAAO,KACvG,IAAMI,EAASR,EAAG,iBAAiBI,EAAUN,EAAG,aAAaM,EAAU,MAAM,EAAGJ,EAAG,aAAa,OAAQ,EAAI,EAEtGyB,kBAAW,IAAI,IACrB,IAAK,IAAMC,KAAalB,EAAO,WAAY,CACzC,GACE,CAACR,EAAG,oBAAoB0B,CAAS,GACjC,CAAC1B,EAAG,oBAAoB0B,EAAU,eAAe,GACjDA,EAAU,gBAAgB,OAAS,8BACnCA,EAAU,cAAc,WAExB,SACF,IAAMC,EAAWD,EAAU,cAAc,cACzC,GAAIC,GAAY3B,EAAG,eAAe2B,CAAQ,EACxC,IAAK,IAAMC,KAAWD,EAAS,SAAU,CACvC,IAAME,GAAQD,EAAQ,cAAgBA,EAAQ,KAAA,CAAM,KAChD,CAACA,EAAQ,YAAcZ,EAAiBa,IAAOJ,EAAS,IAAIG,EAAQ,KAAK,KAAMC,CAAI,CACzF,CACJ,CACA,GAAI,CAACJ,EAAS,KAAM,OAAO,KAC3B,IAAMK,EAAOzB,EAAS,MAAMY,CAAY,CAAC,GAAG,GACtCV,EAAqB,CAAC,EACtBE,EAAS,GAAwB,CACrC,IAAMY,EACJrB,EAAG,iBAAiBU,CAAI,GAAKV,EAAG,aAAaU,EAAK,UAAU,EAAIe,EAAS,IAAIf,EAAK,WAAW,IAAI,EAAI,IAAA,GACvG,GAAIW,GAAcrB,EAAG,iBAAiBU,CAAI,EAAG,CAC3C,IAAMqB,EAAOf,EAAiBK,GAC1BS,IAASC,IAAUA,IAAS,gBAAkB1B,IAAa,uCAC7DE,EAAS,KAAK,GAAGc,EAAW,4CAA4CU,GAAM,EAChF,IAAMC,EAAOd,EAAaG,EAAYX,CAAI,EACtCsB,IAAS,IAAA,IAAa,CAACjB,EAAK,KAAKiB,CAAI,GACvCzB,EAAS,KAAK,SAASyB,EAAK,sEAAsE,CACtG,CACAhC,EAAG,aAAaU,EAAMD,CAAK,CAC7B,EAEA,OADAA,EAAMD,CAAM,EACLD,EAAS,OAAS,CAAC,GAAG,IAAI,IAAIA,CAAQ,CAAC,CAAC,CAAC,KAAK;CAAI,EAAI,IAC/D,CACF,EAEM0B,EAAyB,CAC7B,KAAM,UACN,MAAO,CAAE,uBAAwB9B,EAAc,2BAA4BqB,CAAgB,EAC3F,SAAU,CACR,UAAW,CAAE,YAAarB,EAAa,KAAM,SAAU,CAAC,cAAe,cAAc,CAAE,EACvF,mBAAoB,CAAE,YAAaqB,EAAgB,KAAM,SAAU,CAAC,+BAA+B,CAAE,CACvG,EACA,QAAS,CAAE,YAAa,CAAE,MAAO,CAAE,uBAAwB,QAAS,2BAA4B,OAAQ,CAAE,CAAE,CAC9G"}
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@agimon-ai/vibe-lint-plugin-po-core",
3
+ "version": "0.0.0-alpha.10",
4
+ "description": "Architecture rules for Po core packages",
5
+ "keywords": [
6
+ "lint",
7
+ "po",
8
+ "typescript",
9
+ "vibe-lint"
10
+ ],
11
+ "homepage": "https://agimon.ai",
12
+ "bugs": {
13
+ "url": "https://github.com/AgiFlow/po/issues"
14
+ },
15
+ "license": "MIT",
16
+ "author": "Vuong Ngo",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/AgiFlow/po.git",
20
+ "directory": "packages/tooling/vibe-lint-plugin-po-core"
21
+ },
22
+ "files": [
23
+ "dist",
24
+ "README.md"
25
+ ],
26
+ "type": "module",
27
+ "sideEffects": false,
28
+ "main": "./dist/index.cjs",
29
+ "module": "./dist/index.mjs",
30
+ "types": "./dist/index.d.mts",
31
+ "exports": {
32
+ ".": {
33
+ "types": "./dist/index.d.mts",
34
+ "import": "./dist/index.mjs",
35
+ "require": "./dist/index.cjs"
36
+ },
37
+ "./package.json": "./package.json"
38
+ },
39
+ "publishConfig": {
40
+ "access": "public"
41
+ },
42
+ "dependencies": {
43
+ "typescript": "6.0.3"
44
+ },
45
+ "devDependencies": {
46
+ "@agimon-ai/vibe-lint": "0.0.1-alpha.60",
47
+ "@types/node": "26.6.5",
48
+ "@vitest/coverage-v8": "5.0.4",
49
+ "tsdown": "0.23.1",
50
+ "vitest": "5.0.4"
51
+ },
52
+ "peerDependencies": {
53
+ "@agimon-ai/vibe-lint": "0.0.1-alpha.60"
54
+ },
55
+ "engines": {
56
+ "node": ">=24"
57
+ },
58
+ "scripts": {
59
+ "build": "tsdown",
60
+ "test": "vitest --run",
61
+ "typecheck": "tsc --noEmit",
62
+ "lint": "oxlint . && oxfmt . --check",
63
+ "fixcode": "oxlint . --fix && oxfmt ."
64
+ }
65
+ }