openprompt-lang 0.10.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +53 -21
- package/bin/create.js +56 -56
- package/bin/lint.js +13 -13
- package/bin/opl.js +27 -0
- package/docs/AI_CONTEXT.md +28 -10
- package/docs/FRAMEWORK.md +141 -27
- package/docs/flows/autenticacion-mpfr52fu.md +28 -0
- package/package.json +2 -1
- package/src/ai/prompt-builder.js +2 -2
- package/src/ai/providers.js +4 -1
- package/src/annotations/tags.json +2 -1
- package/src/cli/commands-context.js +27 -19
- package/src/cli/commands-init.js +12 -5
- package/src/cli/commands-misc.js +11 -1
- package/src/cli/commands-opl.js +260 -0
- package/src/commands/component.js +1 -1
- package/src/commands/context.js +1 -1
- package/src/commands/db-rules.js +1 -1
- package/src/commands/init-core.js +3 -3
- package/src/commands/init-existing.js +132 -40
- package/src/commands/init-helpers.js +1 -1
- package/src/commands/integrate.js +3 -0
- package/src/commands/knowledge-helpers.js +84 -0
- package/src/commands/knowledge-query.js +2 -2
- package/src/commands/learning.js +1 -1
- package/src/commands/opl-assess-detect.js +269 -0
- package/src/commands/opl-assess-display.js +217 -0
- package/src/commands/opl-assess-scoring.js +216 -0
- package/src/commands/opl-assess.js +87 -0
- package/src/commands/opl-context-build.js +136 -0
- package/src/commands/opl-context-index.js +362 -0
- package/src/commands/opl-context.js +286 -0
- package/src/commands/opl-contracts.js +182 -0
- package/src/commands/opl-doc-flow.js +215 -0
- package/src/commands/opl-graph.js +206 -0
- package/src/commands/opl-help.js +79 -0
- package/src/commands/opl-index.js +254 -0
- package/src/commands/opl-init-knowledge.js +209 -0
- package/src/commands/opl-read.js +249 -0
- package/src/commands/opl-search.js +253 -0
- package/src/commands/opl-session.js +395 -0
- package/src/commands/opl-system.js +266 -0
- package/src/commands/opl-tutorial.js +226 -0
- package/src/commands/opl-upgrade.js +198 -0
- package/src/commands/pattern.js +2 -2
- package/src/commands/validate.js +239 -212
- package/src/mcp-server.js +1 -1
- package/src/mcp-workflow.js +2 -2
- package/src/templates/knowledge-repo/processed/index/index.json +783 -1
- package/src/templates/knowledge-repo/taxonomy/domains.json +257 -30
- package/src/templates/knowledge-repo/taxonomy/production-readiness.json +393 -0
- package/src/templates/knowledge-repo/taxonomy/systems.json +506 -0
- package/src/templates/langs/react/templates/hooks/use-reducer-form.ts +2 -2
- package/src/utils/annotations-parse.js +271 -0
- package/src/utils/annotations.js +80 -367
- package/src/utils/config.js +32 -1
- package/src/utils/errors.js +141 -0
- package/src/utils/file-utils.js +1 -1
- package/src/utils/generate-framework-md.js +57 -351
- package/src/utils/generate-framework-sections.js +553 -0
- package/src/utils/knowledge-search.js +2 -2
- package/src/utils/pipeline.js +181 -0
package/bin/cli.js
CHANGED
|
@@ -2,33 +2,59 @@
|
|
|
2
2
|
// @use(commander, kind, contract, limit)
|
|
3
3
|
// @kind(util)
|
|
4
4
|
// @contract(in: argv -> out: void, sideEffect: ejecuta CLI)
|
|
5
|
-
// @limit(lines:
|
|
6
|
-
|
|
7
|
-
import { Command } from
|
|
8
|
-
import chalk from
|
|
9
|
-
import { readFileSync } from
|
|
10
|
-
import { join, dirname } from
|
|
11
|
-
import { fileURLToPath } from
|
|
12
|
-
|
|
13
|
-
import { register as registerInit } from
|
|
14
|
-
import { register as registerContext } from
|
|
15
|
-
import { register as registerAi } from
|
|
16
|
-
import { register as registerLang } from
|
|
17
|
-
import { register as registerKnowledge } from
|
|
18
|
-
import { register as registerWork } from
|
|
19
|
-
import { register as registerLearning } from
|
|
20
|
-
import { register as
|
|
5
|
+
// @limit(lines: 90)
|
|
6
|
+
|
|
7
|
+
import { Command } from "commander"
|
|
8
|
+
import chalk from "chalk"
|
|
9
|
+
import { readFileSync } from "fs"
|
|
10
|
+
import { join, dirname } from "path"
|
|
11
|
+
import { fileURLToPath } from "url"
|
|
12
|
+
|
|
13
|
+
import { register as registerInit } from "../src/cli/commands-init.js"
|
|
14
|
+
import { register as registerContext } from "../src/cli/commands-context.js"
|
|
15
|
+
import { register as registerAi } from "../src/cli/commands-ai.js"
|
|
16
|
+
import { register as registerLang } from "../src/cli/commands-lang.js"
|
|
17
|
+
import { register as registerKnowledge } from "../src/cli/commands-knowledge.js"
|
|
18
|
+
import { register as registerWork } from "../src/cli/commands-work.js"
|
|
19
|
+
import { register as registerLearning } from "../src/cli/commands-learning.js"
|
|
20
|
+
import { register as registerOpl } from "../src/cli/commands-opl.js"
|
|
21
|
+
import { register as registerMisc } from "../src/cli/commands-misc.js"
|
|
22
|
+
|
|
23
|
+
import { handleUncaughtErrors, EXIT_CODES } from "../src/utils/errors.js"
|
|
24
|
+
|
|
25
|
+
// Global error handler for uncaught exceptions
|
|
26
|
+
handleUncaughtErrors()
|
|
21
27
|
|
|
22
28
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
23
|
-
const pkg = JSON.parse(readFileSync(join(__dirname,
|
|
29
|
+
const pkg = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8"))
|
|
30
|
+
|
|
31
|
+
// ──────────────────────────────────────────────
|
|
32
|
+
// Si no hay argumentos o solo --help/-h, mostrar bienvenida OPL
|
|
33
|
+
// ──────────────────────────────────────────────
|
|
34
|
+
const args = process.argv.slice(2)
|
|
35
|
+
const isHelpOnly = args.length === 1 && (args[0] === "--help" || args[0] === "-h")
|
|
36
|
+
const hasNoArgs = args.length === 0
|
|
37
|
+
|
|
38
|
+
if (hasNoArgs || isHelpOnly) {
|
|
39
|
+
const { showWelcome } = await import("../src/commands/opl-help.js")
|
|
40
|
+
await showWelcome()
|
|
41
|
+
process.exit(0)
|
|
42
|
+
}
|
|
24
43
|
|
|
25
44
|
const program = new Command()
|
|
26
45
|
|
|
46
|
+
// Override: --help muestra la welcome screen, no la lista de Commander
|
|
47
|
+
program.helpInformation = () => ""
|
|
48
|
+
|
|
27
49
|
program
|
|
28
|
-
.name(
|
|
29
|
-
.description(chalk.cyan(
|
|
50
|
+
.name("openPrompt-Lang")
|
|
51
|
+
.description(chalk.cyan("Context Engine de anotaciones para desarrollo asistido por IA"))
|
|
30
52
|
.version(pkg.version)
|
|
31
53
|
|
|
54
|
+
// Registrar comandos OPL (puerta de entrada: help, tutorial, index, read)
|
|
55
|
+
registerOpl(program)
|
|
56
|
+
|
|
57
|
+
// Registrar comandos existentes
|
|
32
58
|
registerInit(program)
|
|
33
59
|
registerContext(program)
|
|
34
60
|
registerAi(program)
|
|
@@ -41,6 +67,12 @@ registerMisc(program)
|
|
|
41
67
|
try {
|
|
42
68
|
await program.parseAsync(process.argv)
|
|
43
69
|
} catch (err) {
|
|
44
|
-
|
|
45
|
-
|
|
70
|
+
if (err.exitCode !== undefined) {
|
|
71
|
+
console.error('\n' + err.userMessage + '\n')
|
|
72
|
+
process.exitCode = err.exitCode
|
|
73
|
+
} else {
|
|
74
|
+
console.error(chalk.red(`\n✘ Error inesperado: ${err.message}\n`))
|
|
75
|
+
if (process.env.DEBUG) console.error(chalk.gray(err.stack))
|
|
76
|
+
process.exitCode = EXIT_CODES.GENERIC
|
|
77
|
+
}
|
|
46
78
|
}
|
package/bin/create.js
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { execSync } from
|
|
4
|
-
import { readFileSync, writeFileSync, existsSync, mkdirSync, copyFileSync, rmSync } from
|
|
5
|
-
import { join, dirname } from
|
|
6
|
-
import { fileURLToPath } from
|
|
7
|
-
import chalk from
|
|
3
|
+
import { execSync } from "child_process"
|
|
4
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync, copyFileSync, rmSync } from "fs"
|
|
5
|
+
import { join, dirname } from "path"
|
|
6
|
+
import { fileURLToPath } from "url"
|
|
7
|
+
import chalk from "chalk"
|
|
8
8
|
|
|
9
9
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
10
10
|
|
|
11
|
-
async function main
|
|
11
|
+
async function main() {
|
|
12
12
|
const args = process.argv.slice(2)
|
|
13
|
-
const projectName = args[0] ||
|
|
14
|
-
const depsIndex = args.indexOf(
|
|
15
|
-
const deps = depsIndex !== -1 ? args[depsIndex + 1]?.split(
|
|
16
|
-
const deployIndex = args.indexOf(
|
|
13
|
+
const projectName = args[0] || "mi-app"
|
|
14
|
+
const depsIndex = args.indexOf("--deps")
|
|
15
|
+
const deps = depsIndex !== -1 ? args[depsIndex + 1]?.split(",") || [] : []
|
|
16
|
+
const deployIndex = args.indexOf("--deploy")
|
|
17
17
|
const deploy = deployIndex !== -1 ? args[deployIndex + 1] : null
|
|
18
|
-
const hasIonic = args.includes(
|
|
19
|
-
const hasTauri = args.includes(
|
|
20
|
-
const force = args.includes(
|
|
18
|
+
const hasIonic = args.includes("--ionic")
|
|
19
|
+
const hasTauri = args.includes("--tauri")
|
|
20
|
+
const force = args.includes("--force")
|
|
21
21
|
|
|
22
22
|
const projectDir = join(process.cwd(), projectName)
|
|
23
23
|
|
|
@@ -25,22 +25,22 @@ async function main () {
|
|
|
25
25
|
|
|
26
26
|
// 1. Crear con Vite
|
|
27
27
|
try {
|
|
28
|
-
console.log(chalk.blue(
|
|
28
|
+
console.log(chalk.blue(" [1/5] Creando base Vite + React + TS..."))
|
|
29
29
|
execSync(
|
|
30
|
-
`npx create-vite@latest ${projectName} --template react-ts ${force ?
|
|
30
|
+
`npx create-vite@latest ${projectName} --template react-ts ${force ? "--force" : ""}`,
|
|
31
31
|
{
|
|
32
|
-
stdio:
|
|
33
|
-
cwd: process.cwd()
|
|
32
|
+
stdio: "pipe",
|
|
33
|
+
cwd: process.cwd(),
|
|
34
34
|
}
|
|
35
35
|
)
|
|
36
|
-
console.log(chalk.green(
|
|
36
|
+
console.log(chalk.green(" ✅ Base Vite creada"))
|
|
37
37
|
} catch {
|
|
38
|
-
console.log(chalk.yellow(
|
|
38
|
+
console.log(chalk.yellow(" ⚠️ Vite base ya existe o falló. Continuando..."))
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
// 2. Limpiar boilerplate predecible
|
|
42
|
-
console.log(chalk.blue(
|
|
43
|
-
const toDelete = [
|
|
42
|
+
console.log(chalk.blue(" [2/5] Limpiando boilerplate innecesario..."))
|
|
43
|
+
const toDelete = ["src/App.css", "src/assets", "public/vite.svg"]
|
|
44
44
|
for (const file of toDelete) {
|
|
45
45
|
const fullPath = join(projectDir, file)
|
|
46
46
|
if (existsSync(fullPath)) {
|
|
@@ -54,34 +54,34 @@ async function main () {
|
|
|
54
54
|
|
|
55
55
|
export default App
|
|
56
56
|
`
|
|
57
|
-
writeFileSync(join(projectDir,
|
|
57
|
+
writeFileSync(join(projectDir, "src/App.tsx"), appContent, "utf-8")
|
|
58
58
|
|
|
59
59
|
// 3. Instalar dependencias adicionales
|
|
60
60
|
if (deps.length > 0) {
|
|
61
|
-
console.log(chalk.blue(` [3/5] Instalando dependencias: ${deps.join(
|
|
61
|
+
console.log(chalk.blue(` [3/5] Instalando dependencias: ${deps.join(", ")}...`))
|
|
62
62
|
try {
|
|
63
|
-
execSync(`npm install ${deps.join(
|
|
64
|
-
console.log(chalk.green(
|
|
63
|
+
execSync(`npm install ${deps.join(" ")}`, { stdio: "pipe", cwd: projectDir })
|
|
64
|
+
console.log(chalk.green(" ✅ Dependencias instaladas"))
|
|
65
65
|
} catch {
|
|
66
66
|
console.log(
|
|
67
|
-
chalk.yellow(
|
|
67
|
+
chalk.yellow(" ⚠️ Error instalando dependencias. Continúa con npm install manual.")
|
|
68
68
|
)
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
// 4. Copiar scaffolds
|
|
73
|
-
console.log(chalk.blue(
|
|
74
|
-
const scaffoldsDir = join(__dirname,
|
|
73
|
+
console.log(chalk.blue(" [4/5] Copiando archivos de configuración..."))
|
|
74
|
+
const scaffoldsDir = join(__dirname, "..", "scaffolds")
|
|
75
75
|
|
|
76
76
|
const scaffoldFiles = [
|
|
77
|
-
[
|
|
78
|
-
[
|
|
77
|
+
["tailwind.config.js", "tailwind.config.js"],
|
|
78
|
+
["prompt-lang.json", "prompt-lang.json"],
|
|
79
79
|
]
|
|
80
80
|
|
|
81
|
-
if (deploy ===
|
|
82
|
-
if (deploy ===
|
|
83
|
-
if (hasIonic) scaffoldFiles.push([
|
|
84
|
-
if (hasTauri) scaffoldFiles.push([
|
|
81
|
+
if (deploy === "railway") scaffoldFiles.push(["railway.json", "railway.json"])
|
|
82
|
+
if (deploy === "netlify") scaffoldFiles.push(["netlify.toml", "netlify.toml"])
|
|
83
|
+
if (hasIonic) scaffoldFiles.push(["capacitor.config.ts", "capacitor.config.ts"])
|
|
84
|
+
if (hasTauri) scaffoldFiles.push(["tauri.conf.json", "tauri.conf.json"])
|
|
85
85
|
|
|
86
86
|
for (const [src, dest] of scaffoldFiles) {
|
|
87
87
|
const srcPath = join(scaffoldsDir, src)
|
|
@@ -93,43 +93,43 @@ export default App
|
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
// 5. Configurar package.json con scripts descriptivos
|
|
96
|
-
console.log(chalk.blue(
|
|
97
|
-
const pkgPath = join(projectDir,
|
|
96
|
+
console.log(chalk.blue(" [5/5] Agregando scripts descriptivos..."))
|
|
97
|
+
const pkgPath = join(projectDir, "package.json")
|
|
98
98
|
if (existsSync(pkgPath)) {
|
|
99
|
-
const pkg = JSON.parse(readFileSync(pkgPath,
|
|
99
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"))
|
|
100
100
|
const descriptiveScripts = {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
101
|
+
"dev:start": "vite",
|
|
102
|
+
"dev:preview": "vite preview",
|
|
103
|
+
"build:prod": "vite build",
|
|
104
|
+
"build:analyze": "vite build --analyze",
|
|
105
|
+
"lint:check": "eslint src --ext .ts,.tsx",
|
|
106
|
+
"lint:fix": "eslint src --ext .ts,.tsx --fix",
|
|
107
|
+
"type:check": "tsc --noEmit",
|
|
108
|
+
"test:unit": "vitest run",
|
|
109
|
+
"test:watch": "vitest",
|
|
110
|
+
"test:coverage": "vitest run --coverage",
|
|
111
|
+
"validate:all": "npm run lint:check && npm run type:check && npm run test:unit",
|
|
112
112
|
}
|
|
113
113
|
pkg.scripts = { ...descriptiveScripts, ...pkg.scripts }
|
|
114
|
-
writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)
|
|
115
|
-
console.log(chalk.green(
|
|
114
|
+
writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`, "utf-8")
|
|
115
|
+
console.log(chalk.green(" ✅ Scripts descriptivos agregados"))
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
// Ionic plug
|
|
119
119
|
if (hasIonic) {
|
|
120
|
-
console.log(chalk.blue(
|
|
120
|
+
console.log(chalk.blue(" 🔌 Integrando Ionic..."))
|
|
121
121
|
try {
|
|
122
|
-
execSync(
|
|
123
|
-
execSync(
|
|
124
|
-
console.log(chalk.green(
|
|
122
|
+
execSync("npx cap init App com.app.app --web-dir=dist", { stdio: "pipe", cwd: projectDir })
|
|
123
|
+
execSync("npx cap add android", { stdio: "pipe", cwd: projectDir })
|
|
124
|
+
console.log(chalk.green(" ✅ Ionic/Capacitor configurado"))
|
|
125
125
|
} catch {
|
|
126
|
-
console.log(chalk.yellow(
|
|
126
|
+
console.log(chalk.yellow(" ⚠️ Error en setup Ionic. Configura manualmente."))
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
console.log(chalk.cyan(`\n✅ ${projectName} listo!`))
|
|
131
131
|
console.log(chalk.cyan(` cd ${projectName}`))
|
|
132
|
-
console.log(chalk.cyan(
|
|
132
|
+
console.log(chalk.cyan(" npm run dev:start\n"))
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
main().catch(console.error)
|
package/bin/lint.js
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { readFileSync, existsSync } from
|
|
4
|
-
import { join } from
|
|
5
|
-
import { lintFile } from
|
|
6
|
-
import chalk from
|
|
3
|
+
import { readFileSync, existsSync } from "fs"
|
|
4
|
+
import { join } from "path"
|
|
5
|
+
import { lintFile } from "../src/utils/annotations.js"
|
|
6
|
+
import chalk from "chalk"
|
|
7
7
|
|
|
8
|
-
const targetFile = join(process.cwd(), process.argv[2] ||
|
|
8
|
+
const targetFile = join(process.cwd(), process.argv[2] || "")
|
|
9
9
|
|
|
10
10
|
if (!targetFile || !existsSync(targetFile)) {
|
|
11
|
-
console.log(chalk.red(
|
|
12
|
-
console.log(
|
|
11
|
+
console.log(chalk.red("❌ Archivo no encontrado"))
|
|
12
|
+
console.log("Uso: node bin/lint.js <archivo>")
|
|
13
13
|
process.exit(1)
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
const content = readFileSync(targetFile,
|
|
16
|
+
const content = readFileSync(targetFile, "utf-8")
|
|
17
17
|
const { annotations, errors, warnings } = lintFile(content)
|
|
18
18
|
|
|
19
19
|
if (annotations.length === 0) {
|
|
20
|
-
console.log(chalk.cyan(
|
|
20
|
+
console.log(chalk.cyan("📭 Sin anotaciones PromptLang en este archivo"))
|
|
21
21
|
process.exit(0)
|
|
22
22
|
}
|
|
23
23
|
|
|
@@ -25,9 +25,9 @@ console.log(chalk.cyan(`\n🔍 Anotaciones encontradas: ${annotations.length}\n`
|
|
|
25
25
|
|
|
26
26
|
for (const ann of annotations) {
|
|
27
27
|
const argsStr = ann.args.length
|
|
28
|
-
? ann.args.map((a) => (a.key ? `${a.key}: ${a.value}` : a.value)).join(
|
|
29
|
-
:
|
|
30
|
-
console.log(` @${ann.name}${argsStr ? `(${argsStr})` :
|
|
28
|
+
? ann.args.map((a) => (a.key ? `${a.key}: ${a.value}` : a.value)).join(", ")
|
|
29
|
+
: ""
|
|
30
|
+
console.log(` @${ann.name}${argsStr ? `(${argsStr})` : ""}`)
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
if (errors.length > 0) {
|
|
@@ -45,5 +45,5 @@ if (warnings.length > 0) {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
if (errors.length === 0 && warnings.length === 0) {
|
|
48
|
-
console.log(chalk.green(
|
|
48
|
+
console.log(chalk.green("\n✅ Todas las anotaciones válidas\n"))
|
|
49
49
|
}
|
package/bin/opl.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// @use(kind, contract, limit)
|
|
3
|
+
// @kind(util)
|
|
4
|
+
// @contract(in: argv -> out: exitCode, sideEffect: delega a cli.js con los mismos argumentos)
|
|
5
|
+
// @limit(lines: 30)
|
|
6
|
+
|
|
7
|
+
// Shortcut: 'opl' → 'openPrompt-Lang'
|
|
8
|
+
// Este archivo permite usar 'opl' como comando corto en vez de 'openPrompt-Lang'
|
|
9
|
+
// Ej: opl validate, opl assess, opl search react
|
|
10
|
+
|
|
11
|
+
import { fileURLToPath } from 'url'
|
|
12
|
+
import { dirname, join } from 'path'
|
|
13
|
+
import { execFileSync } from 'child_process'
|
|
14
|
+
|
|
15
|
+
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
16
|
+
const cliPath = join(__dirname, 'cli.js')
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
const result = execFileSync(process.execPath, [cliPath, ...process.argv.slice(2)], {
|
|
20
|
+
cwd: process.cwd(),
|
|
21
|
+
stdio: 'inherit',
|
|
22
|
+
env: { ...process.env, OPL_ALIAS: '1' }
|
|
23
|
+
})
|
|
24
|
+
process.exitCode = result?.status ?? 0
|
|
25
|
+
} catch (err) {
|
|
26
|
+
process.exitCode = err.status ?? 1
|
|
27
|
+
}
|
package/docs/AI_CONTEXT.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
## 1. Resumen corto
|
|
4
4
|
- Proyecto: openPrompt-Lang — context engine de anotaciones y templates para desarrollo asistido por IA
|
|
5
5
|
- Objetivo: IA local especializada en desarrollo asistido con contexto reducido y pasos pequeños.
|
|
6
|
-
- Versión: 0.
|
|
6
|
+
- Versión: 0.10.1 (CLI), módulos de lenguaje v1.0.0–1.1.0
|
|
7
7
|
|
|
8
8
|
## 2. Stack técnico
|
|
9
9
|
- Frontend: React 19 + TypeScript + Vite 7 + Tailwind v4
|
|
@@ -30,18 +30,36 @@ controller, service, route, middleware, model, repository, util, type, prisma, s
|
|
|
30
30
|
Controller, Service, Repository, DTOs, Entity, GlobalExceptionHandler, FeignClient, KafkaConfig
|
|
31
31
|
|
|
32
32
|
## 4. Base de conocimiento
|
|
33
|
-
- **
|
|
33
|
+
- **13 dominios**: payments, mobile-pwa, systems, qa, frontend, backend, accessibility, algorithms, fundamentals, architecture, typescript, saas, restaurant
|
|
34
34
|
- **13 playbooks**: flow-integration, capacitor-setup, rust-ownership, scrum-workflow, frontend-react, backend-nodejs, accessibility-wcag, algorithms-patterns, fundamentals-programs, spa-auth-flow, api-rest-design, db-schema-design, microservice-architecture
|
|
35
|
-
- **
|
|
35
|
+
- **35 fuentes** de conocimiento (libros/docs + 2 proyectos reales extraídos)
|
|
36
|
+
- **10 sistemas de conocimiento**: react-fullstack-app, sistema-pagos-chile, microservicios-spring, app-movil-offline, sistema-restaurant-pos, api-rest-robusta, accesibilidad-wcag-chile, typescript-avanzado, microservicios-multi-lenguaje, saas-pos-chileno
|
|
36
37
|
|
|
37
|
-
## 5. Comandos
|
|
38
|
+
## 5. Comandos OPL
|
|
38
39
|
```bash
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
# Navegación de conocimiento
|
|
41
|
+
opl index [path] # Navegar por niveles
|
|
42
|
+
opl read <dominio>/<id> # Leer contenido (--chapter n --full)
|
|
43
|
+
opl search <query> # Búsqueda híbrida (+ detecta sistema)
|
|
44
|
+
opl system [name] # Explorar sistemas de conocimiento
|
|
45
|
+
opl graph [concept] # Grafo de relaciones
|
|
46
|
+
|
|
47
|
+
# Evaluación de proyectos
|
|
48
|
+
opl assess [path] # PRA score 0-100
|
|
49
|
+
opl assess --verbose # 7 dimensiones × 28 criterios
|
|
50
|
+
opl assess --save # Guardar reporte JSON
|
|
51
|
+
|
|
52
|
+
# Configuración y sesiones
|
|
53
|
+
opl init --knowledge # Biblioteca personal ~/.opl/knowledge/
|
|
54
|
+
opl session doc/close/diff # Gestión de sesiones
|
|
55
|
+
opl doc flow/framework # Documentación (Mermaid, FRAMEWORK.md)
|
|
56
|
+
opl upgrade # Migrar configuración
|
|
57
|
+
|
|
58
|
+
# Templates y validación
|
|
59
|
+
npx openPrompt-Lang validate # Validar anotaciones
|
|
60
|
+
npx openPrompt-Lang lang list # Listar módulos
|
|
61
|
+
npx openPrompt-Lang teach <id> # Aprender de un template
|
|
62
|
+
npx openPrompt-Lang qa-gen # Generar tests de regresión
|
|
45
63
|
```
|
|
46
64
|
|
|
47
65
|
## 6. Referencia canónica
|