jorgex-stack 1.0.22 → 1.0.24

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/README.md CHANGED
@@ -24,6 +24,8 @@ For development from a clone, run the same commands through `pnpm cli <command>`
24
24
 
25
25
  Every command supports `--dry-run`, `--yes`, and `--target-dir <dir>` for testing without touching the real config. Writes create automatic backups and verify idempotency; merges into user config are surgical (marked markdown sections, JSON/TOML upserts), so user-owned content is never touched.
26
26
 
27
+ Runtime defaults are documented in [docs/references/permissions.md](docs/references/permissions.md) for permissions and [docs/references/models.md](docs/references/models.md) for model selection, GPT-5.6 subagent tiers, and orchestrator inheritance.
28
+
27
29
  ### Modes: Human and Programmatic
28
30
 
29
31
  `install` and `sync` accept two mutually-exclusive installation modes. The choice is global (not per runtime) and is saved in `~/.jorgex-stack/install-mode.json` on first run; subsequent `sync` calls reuse it. Re-run `install` with `--mode` to switch.
package/dist/cli.js CHANGED
@@ -179,21 +179,22 @@ function resolveAgentModel(models, agentName, tier) {
179
179
  }
180
180
  var DEFAULT_MODEL_MAP = {
181
181
  opencode: {
182
- strong: { model: "openai/gpt-5.4", variant: "high" },
183
- standard: { model: "openai/gpt-5.4-mini", variant: "high" },
184
- cheap: { model: "minimax/MiniMax-M3" }
182
+ strong: { model: "openai/gpt-5.6-terra", variant: "xhigh" },
183
+ standard: { model: "openai/gpt-5.6-terra", variant: "xhigh" },
184
+ cheap: { model: "openai/gpt-5.6-luna", variant: "medium" }
185
185
  },
186
186
  "claude-code": {
187
187
  strong: { model: "fable" },
188
188
  standard: { model: "sonnet" },
189
189
  cheap: { model: "haiku" }
190
190
  },
191
- // Codex: "default" = no fijar modelo (usa el del CLI, que OpenAI actualiza
192
- // solo D6); variant model_reasoning_effort.
191
+ // El primary (orchestrator) no usa estos tiers: tanto el profile de CLI como
192
+ // la skill de la app heredan el modelo elegido por el usuario. Estos defaults
193
+ // son solo para subagentes; variant → model_reasoning_effort.
193
194
  codex: {
194
- strong: { model: "default", variant: "high" },
195
- standard: { model: "default", variant: "medium" },
196
- cheap: { model: "default", variant: "low" }
195
+ strong: { model: "gpt-5.6-terra", variant: "xhigh" },
196
+ standard: { model: "gpt-5.6-terra", variant: "xhigh" },
197
+ cheap: { model: "gpt-5.6-luna", variant: "medium" }
197
198
  }
198
199
  };
199
200
  function modelMapFile() {
@@ -614,11 +615,17 @@ ${agent.body}`,
614
615
  planMainConfig(canonical, ctx) {
615
616
  const file = path7.join(ctx.configDir, "opencode.json");
616
617
  const { pluginsDir } = this.paths(ctx.configDir);
617
- const content = upsertJson(readTextIfExists(file), (root) => {
618
+ const original = readTextIfExists(file);
619
+ const contentSource = original === null || original.trim() === "" ? null : original;
620
+ const isFreshConfig = contentSource === null;
621
+ const content = upsertJson(contentSource, (root) => {
618
622
  root["$schema"] ??= "https://opencode.ai/config.json";
619
623
  const defaults = loadCanonicalDefaults(ctx.stackDir)["opencode"];
620
- if (defaults?.["permission"] !== void 0 && !("permission" in root)) {
624
+ if (isFreshConfig && defaults?.["permission"] !== void 0) {
621
625
  root["permission"] = defaults["permission"];
626
+ ctx.warnings.push(
627
+ "OpenCode: fresh config enables read-anywhere via external_directory:*; edits, web egress and arbitrary bash remain approval-gated, but broad local reads can expose secrets not covered by deny rules."
628
+ );
622
629
  }
623
630
  const mcp = root["mcp"] ??= {};
624
631
  for (const [name, server] of Object.entries(canonical.servers)) {
@@ -818,12 +825,19 @@ ${agent.body}`,
818
825
  planHooks(canonical, ctx) {
819
826
  const actions = [];
820
827
  const { scriptsDir } = this.paths(ctx.configDir);
828
+ const original = readTextIfExists(path8.join(ctx.configDir, "settings.json"));
829
+ const contentSource = original === null || original.trim() === "" ? null : original;
821
830
  const settingsFile = path8.join(ctx.configDir, "settings.json");
822
- let content = upsertNativeHooks(readTextIfExists(settingsFile), canonical, scriptsDir);
831
+ let content = upsertNativeHooks(contentSource, canonical, scriptsDir);
823
832
  const defaults = loadCanonicalDefaults(ctx.stackDir)["claude-code"];
824
- if (defaults?.["permissions"] !== void 0) {
833
+ if (contentSource === null && defaults?.["permissions"] !== void 0) {
825
834
  content = upsertJson(content, (root) => {
826
- if (!("permissions" in root)) root["permissions"] = defaults["permissions"];
835
+ if (root["permissions"] === void 0) {
836
+ root["permissions"] = defaults["permissions"];
837
+ ctx.warnings.push(
838
+ "Claude Code: fresh config enables read-anywhere via Read/Grep/Glob allow rules; shell, writes and web egress remain approval-gated, but broad local reads can expose secrets not covered by deny rules."
839
+ );
840
+ }
827
841
  });
828
842
  }
829
843
  actions.push({ kind: "write", target: settingsFile, content });
@@ -1026,13 +1040,52 @@ ${body}`
1026
1040
  },
1027
1041
  planMainConfig(canonical, ctx) {
1028
1042
  const file = path9.join(ctx.configDir, "config.toml");
1029
- let content = readTextIfExists(file);
1030
- const defaults = loadCanonicalDefaults(ctx.stackDir)["codex"] ?? {};
1031
- for (const [key, value] of Object.entries(defaults)) {
1032
- if (content !== null && new RegExp(`^\\s*${key}\\s*=`, "m").test(content)) continue;
1033
- const line = `${key} = ${tomlString(String(value))}
1043
+ const original = readTextIfExists(file);
1044
+ const contentSource = original === null || original.trim() === "" ? null : original;
1045
+ let content = contentSource;
1046
+ if (contentSource === null) {
1047
+ const defaults = loadCanonicalDefaults(ctx.stackDir)["codex"] ?? {};
1048
+ for (const [key, value] of Object.entries(defaults)) {
1049
+ const line = `${key} = ${tomlString(String(value))}
1034
1050
  `;
1035
- content = content === null ? line : line + content;
1051
+ content = content === null ? line : line + content;
1052
+ }
1053
+ ctx.warnings.push(
1054
+ "Codex: fresh config enables read-anywhere via the jorgex-read-anywhere permission profile; broad local reads can expose secrets not covered by deny rules."
1055
+ );
1056
+ content = upsertTomlSection(content, "permissions.jorgex-read-anywhere", 'extends = ":workspace"');
1057
+ content = upsertTomlSection(
1058
+ content,
1059
+ "permissions.jorgex-read-anywhere.filesystem",
1060
+ [
1061
+ '":root" = "read"',
1062
+ '"*.env" = "deny"',
1063
+ '"*.env.*" = "deny"',
1064
+ '"~/.ssh/**" = "deny"',
1065
+ '"~/.aws/credentials" = "deny"',
1066
+ '"~/.npmrc" = "deny"',
1067
+ '"~/.git-credentials" = "deny"',
1068
+ '"**/id_rsa" = "deny"',
1069
+ '"**/id_ed25519" = "deny"',
1070
+ '"**/*.pem" = "deny"',
1071
+ '"**/*.key" = "deny"'
1072
+ ].join("\n")
1073
+ );
1074
+ content += [
1075
+ '\n[permissions.jorgex-read-anywhere.filesystem.":workspace_roots"]',
1076
+ '"." = "write"',
1077
+ '"*.env" = "deny"',
1078
+ '"*.env.*" = "deny"',
1079
+ '".ssh/**" = "deny"',
1080
+ '".aws/credentials" = "deny"',
1081
+ '".npmrc" = "deny"',
1082
+ '".git-credentials" = "deny"',
1083
+ '"**/id_rsa" = "deny"',
1084
+ '"**/id_ed25519" = "deny"',
1085
+ '"**/*.pem" = "deny"',
1086
+ '"**/*.key" = "deny"',
1087
+ ""
1088
+ ].join("\n");
1036
1089
  }
1037
1090
  for (const [name, server] of Object.entries(canonical.servers)) {
1038
1091
  const section = `mcp_servers.${name}`;
@@ -2790,7 +2843,15 @@ import * as p5 from "@clack/prompts";
2790
2843
  var TIERS = ["strong", "standard", "cheap"];
2791
2844
  var EFFORTS = ["low", "medium", "high", "xhigh"];
2792
2845
  var CLAUDE_ALIASES = ["fable", "opus", "sonnet", "haiku", "inherit"];
2793
- var CODEX_MODELS = ["default", "gpt-5.5", "gpt-5.4", "gpt-5.4-mini"];
2846
+ var CODEX_MODELS = [
2847
+ "default",
2848
+ "gpt-5.6-sol",
2849
+ "gpt-5.6-terra",
2850
+ "gpt-5.6-luna",
2851
+ "gpt-5.5",
2852
+ "gpt-5.4",
2853
+ "gpt-5.4-mini"
2854
+ ];
2794
2855
  var CODEX_CUSTOM = "__custom__";
2795
2856
  var CANCEL = /* @__PURE__ */ Symbol("cancel");
2796
2857
  function opencodeLiveModels(binPath) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jorgex-stack",
3
- "version": "1.0.22",
3
+ "version": "1.0.24",
4
4
  "description": "Harness multi-agente portable: instala la config JorgeX (agentes, skills, hooks, Engram, MCPs) en Claude Code, Codex CLI y OpenCode",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,17 +1,36 @@
1
1
  {
2
- "$comment": "Permisos por defecto del stack: casi todo permitido, lo destructivo pregunta o se bloquea. REGLA DE ORO: cada bloque se escribe SOLO si el usuario aún no tiene esa clave en su config si ya la tiene (suya o ajustada después), el sync no la toca jamás. Quitar o editar estos valores tras el install es seguro: pasan a ser config del usuario.",
2
+ "$comment": "Permisos por defecto del stack: cada bloque se escribe SOLO en config fresca o vacía; una config existente no se auto-expande jamás. OpenCode fresh default permite leer fuera del cwd, pero deja edit/bash en ask salvo allow explícito para lecturas seguras.",
3
3
  "opencode": {
4
4
  "permission": {
5
- "edit": "allow",
6
- "read": "allow",
5
+ "edit": "ask",
6
+ "read": {
7
+ "*": "allow",
8
+ "*.env": "deny",
9
+ "*.env.*": "deny",
10
+ "*.env.example": "allow",
11
+ "*/.ssh/*": "deny",
12
+ "*/.aws/credentials": "deny",
13
+ "*/.npmrc": "deny",
14
+ "*/.git-credentials": "deny",
15
+ "*/id_rsa": "deny",
16
+ "*/id_ed25519": "deny",
17
+ "*.pem": "deny",
18
+ "*.key": "deny"
19
+ },
20
+ "external_directory": {
21
+ "*": "allow"
22
+ },
7
23
  "glob": "allow",
8
24
  "grep": "allow",
9
25
  "list": "allow",
10
26
  "lsp": "allow",
11
- "webfetch": "allow",
12
- "websearch": "allow",
27
+ "webfetch": "ask",
28
+ "websearch": "ask",
13
29
  "bash": {
14
- "*": "allow",
30
+ "*": "ask",
31
+ "git diff*": "ask",
32
+ "git log*": "allow",
33
+ "git status*": "allow",
15
34
  "rm *": "ask",
16
35
  "del *": "ask",
17
36
  "rmdir *": "ask",
@@ -25,13 +44,28 @@
25
44
  },
26
45
  "claude-code": {
27
46
  "permissions": {
28
- "allow": ["Bash", "Edit", "Write", "WebFetch", "WebSearch"],
29
- "ask": ["Bash(rm:*)", "Bash(rmdir:*)", "Bash(del:*)", "Bash(git push --force:*)"],
30
- "deny": ["Bash(format:*)", "Bash(mkfs:*)", "Bash(dd:*)", "Bash(shred:*)", "Read(./.env)", "Read(./.env.*)"]
47
+ "allow": ["Read", "Grep", "Glob"],
48
+ "ask": ["Bash", "Edit", "Write", "WebFetch", "WebSearch", "Bash(rm:*)", "Bash(rmdir:*)", "Bash(del:*)", "Bash(git push --force:*)"],
49
+ "deny": [
50
+ "Bash(format:*)",
51
+ "Bash(mkfs:*)",
52
+ "Bash(dd:*)",
53
+ "Bash(shred:*)",
54
+ "Read(//**/.env)",
55
+ "Read(//**/.env.*)",
56
+ "Read(//**/.ssh/**)",
57
+ "Read(//**/.aws/credentials)",
58
+ "Read(//**/.npmrc)",
59
+ "Read(//**/.git-credentials)",
60
+ "Read(//**/id_rsa)",
61
+ "Read(//**/id_ed25519)",
62
+ "Read(//**/*.pem)",
63
+ "Read(//**/*.key)"
64
+ ]
31
65
  }
32
66
  },
33
67
  "codex": {
34
68
  "approval_policy": "on-request",
35
- "sandbox_mode": "workspace-write"
69
+ "default_permissions": "jorgex-read-anywhere"
36
70
  }
37
71
  }