jorgex-stack 1.0.7 → 1.0.9
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 +4 -4
- package/dist/cli.js +50 -33
- package/package.json +1 -1
- package/upstreams.json +3 -8
- package/stack/skills/graphify/.graphify_version +0 -1
- package/stack/skills/graphify/SKILL.md +0 -1319
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# JorgeX Stack
|
|
2
2
|
|
|
3
|
-
Portable multi-agent harness: one configuration source — 15 agents,
|
|
3
|
+
Portable multi-agent harness: one configuration source — 15 agents, 17 skills, hooks, persistent memory ([Engram](https://github.com/Gentleman-Programming/engram)), MCPs, and system prompt — installable with one command in **Claude Code**, **Codex CLI**, and **OpenCode**.
|
|
4
4
|
|
|
5
5
|
> Inspired by [gentle-ai](https://github.com/Gentleman-Programming/gentle-ai), rebuilt for the JorgeX stack.
|
|
6
6
|
|
|
@@ -13,7 +13,7 @@ pnpm dlx jorgex-stack install # interactive: choose runtimes and confirm
|
|
|
13
13
|
pnpm dlx jorgex-stack models # model picker by runtime and tier (strong/standard/cheap)
|
|
14
14
|
pnpm dlx jorgex-stack sync # reapplies config (idempotent; removes orphans)
|
|
15
15
|
pnpm dlx jorgex-stack doctor # checks that everything is healthy (Engram, drift, hooks, keys)
|
|
16
|
-
pnpm dlx jorgex-stack update # interactive: scans stack
|
|
16
|
+
pnpm dlx jorgex-stack update # interactive: scans stack + Engram, multiselect, diff/confirm
|
|
17
17
|
# With --check: report only, no changes
|
|
18
18
|
# With --yes: batch mode (report only)
|
|
19
19
|
pnpm dlx jorgex-stack restore # restores a backup
|
|
@@ -26,11 +26,11 @@ Every command supports `--dry-run`, `--yes`, and `--target-dir <dir>` for testin
|
|
|
26
26
|
|
|
27
27
|
### Update: Interactive Flow
|
|
28
28
|
|
|
29
|
-
`update` manages
|
|
29
|
+
`update` manages two sources for the end user, plus a maintainer-only one:
|
|
30
30
|
|
|
31
31
|
1. **Stack** (jorgex-stack): detects whether it is a git clone or a global install, then offers an update with confirmation.
|
|
32
32
|
2. **Engram** (binary): detects the installed version and offers an update through the **native channel** (brew -> `go install` -> release URL). Nothing needs to be stopped: as in upstream macOS/Linux, live processes keep using the old version until clients restart; on Windows, the in-use `.exe` is rotated by rename before installation. **Automatic DB backup before updating**. The database and memories are never touched.
|
|
33
|
-
3. **Vendored skills
|
|
33
|
+
3. **Vendored skills** (maintainer only): third-party skills ship **pinned** with the stack version, so the installed package never reaches out to their upstreams. Only when running from a git clone (`pnpm cli update`) does `update` scan the upstreams in `upstreams.json`, download to a temp directory, **show a mandatory diff**, and ask for confirmation — so the review and re-pin persist in the repo and get published. Skills with local changes (`modified: true`) warn and require double confirmation.
|
|
34
34
|
|
|
35
35
|
Usage:
|
|
36
36
|
- `update --check`: scans versions without applying changes.
|
package/dist/cli.js
CHANGED
|
@@ -1947,6 +1947,9 @@ function loadUpstreams() {
|
|
|
1947
1947
|
const file = path22.join(path22.dirname(stackRoot()), "upstreams.json");
|
|
1948
1948
|
return JSON.parse(fs16.readFileSync(file, "utf8"));
|
|
1949
1949
|
}
|
|
1950
|
+
function skillsToScan(maintainer, upstreams) {
|
|
1951
|
+
return maintainer ? Object.keys(upstreams.skills) : [];
|
|
1952
|
+
}
|
|
1950
1953
|
async function latestNpmVersion(pkg) {
|
|
1951
1954
|
try {
|
|
1952
1955
|
const res = await fetch(`https://registry.npmjs.org/${pkg}/latest`, {
|
|
@@ -1985,37 +1988,45 @@ async function runUpdateCheck(localVersion) {
|
|
|
1985
1988
|
`engram: ${local} local, ${latest} disponible. Tu instalaci\xF3n NO se toca (D7) \u2014 actualiza t\xFA: github.com/${engramRepo}/releases`
|
|
1986
1989
|
);
|
|
1987
1990
|
}
|
|
1988
|
-
const
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
1991
|
+
const checkSkillNames = skillsToScan(isGitClone(), upstreams);
|
|
1992
|
+
if (checkSkillNames.length === 0) {
|
|
1993
|
+
p4.log.info(
|
|
1994
|
+
"Skills de terceros: pineadas con la versi\xF3n del stack (su revisi\xF3n upstream se hace desde el clon del repo)."
|
|
1995
|
+
);
|
|
1996
|
+
} else {
|
|
1997
|
+
const byRepo = /* @__PURE__ */ new Map();
|
|
1998
|
+
for (const name of checkSkillNames) {
|
|
1999
|
+
const info = upstreams.skills[name];
|
|
2000
|
+
const repo = info.source.replace(/^github:/, "");
|
|
2001
|
+
const entry = byRepo.get(repo) ?? { skills: [], pinned: info.commit };
|
|
2002
|
+
entry.skills.push(info.modified ? `${name} (modificada localmente)` : name);
|
|
2003
|
+
byRepo.set(repo, entry);
|
|
2004
|
+
}
|
|
2005
|
+
const heads = await Promise.all(
|
|
2006
|
+
[...byRepo.keys()].map(async (repo) => [repo, await latestGithubCommit(repo)])
|
|
2007
|
+
);
|
|
2008
|
+
let moved = 0;
|
|
2009
|
+
for (const [repo, head] of heads) {
|
|
2010
|
+
const { skills, pinned } = byRepo.get(repo);
|
|
2011
|
+
if (!pinned)
|
|
2012
|
+
p4.log.warn(
|
|
2013
|
+
`${repo}: sin pin en upstreams.json \u2014 a\xF1ade el commit revisado. Skills: ${skills.join(", ")}`
|
|
2014
|
+
);
|
|
2015
|
+
else if (head === null)
|
|
2016
|
+
p4.log.info(`${repo}: pin ${pinned.slice(0, 7)} (no se pudo consultar el upstream).`);
|
|
2017
|
+
else if (head === pinned)
|
|
2018
|
+
p4.log.success(`${repo}: al d\xEDa con el pin ${pinned.slice(0, 7)} (${skills.join(", ")}).`);
|
|
2019
|
+
else {
|
|
2020
|
+
moved++;
|
|
2021
|
+
p4.log.warn(
|
|
2022
|
+
`${repo}: el upstream se movi\xF3 (pin ${pinned.slice(0, 7)} \u2192 ${head.slice(0, 7)}). Skills: ${skills.join(", ")}.
|
|
2013
2023
|
Revisa el diff y, si lo aceptas, actualiza la copia vendorizada y el pin: github.com/${repo}/compare/${pinned.slice(0, 7)}...${head.slice(0, 7)}`
|
|
2014
|
-
|
|
2024
|
+
);
|
|
2025
|
+
}
|
|
2026
|
+
}
|
|
2027
|
+
if (moved === 0 && heads.every(([, head]) => head !== null)) {
|
|
2028
|
+
p4.log.info("Skills de terceros: ning\xFAn upstream se ha movido respecto a su pin.");
|
|
2015
2029
|
}
|
|
2016
|
-
}
|
|
2017
|
-
if (moved === 0 && heads.every(([, head]) => head !== null)) {
|
|
2018
|
-
p4.log.info("Skills de terceros: ning\xFAn upstream se ha movido respecto a su pin.");
|
|
2019
2030
|
}
|
|
2020
2031
|
if (githubRateLimited()) {
|
|
2021
2032
|
p4.log.warn(rateLimitHint("GitHub limit\xF3 algunas consultas (rate limit sin token)."));
|
|
@@ -2046,8 +2057,7 @@ function isEngramRunning() {
|
|
|
2046
2057
|
return null;
|
|
2047
2058
|
}
|
|
2048
2059
|
}
|
|
2049
|
-
function isGitClone() {
|
|
2050
|
-
const projectRoot = path22.dirname(stackRoot());
|
|
2060
|
+
function isGitClone(projectRoot = path22.dirname(stackRoot())) {
|
|
2051
2061
|
return fs16.existsSync(path22.join(projectRoot, ".git"));
|
|
2052
2062
|
}
|
|
2053
2063
|
var STACK_METHOD_CLONE = "git pull + pnpm install + pnpm build";
|
|
@@ -2325,8 +2335,10 @@ async function runInteractiveUpdate(localVersion, yes, dryRun = false) {
|
|
|
2325
2335
|
const upstreams = loadUpstreams();
|
|
2326
2336
|
let exitCode = 0;
|
|
2327
2337
|
let appliedUpdates = false;
|
|
2338
|
+
const maintainer = isGitClone();
|
|
2328
2339
|
const spin = p4.spinner();
|
|
2329
2340
|
spin.start("Consultando versiones upstream\u2026");
|
|
2341
|
+
const skillNames = skillsToScan(maintainer, upstreams);
|
|
2330
2342
|
const [npmLatest, engramLatestRaw, ...skillHeads] = await Promise.all([
|
|
2331
2343
|
latestNpmVersion("jorgex-stack"),
|
|
2332
2344
|
(async () => {
|
|
@@ -2334,7 +2346,7 @@ async function runInteractiveUpdate(localVersion, yes, dryRun = false) {
|
|
|
2334
2346
|
if (!repo) return null;
|
|
2335
2347
|
return { repo, version: await latestGithubRelease(repo) };
|
|
2336
2348
|
})(),
|
|
2337
|
-
...
|
|
2349
|
+
...skillNames.map(async (name) => {
|
|
2338
2350
|
const info = upstreams.skills[name];
|
|
2339
2351
|
const repo = info.source.replace(/^github:/, "");
|
|
2340
2352
|
const head = await latestGithubCommit(repo);
|
|
@@ -2354,7 +2366,7 @@ async function runInteractiveUpdate(localVersion, yes, dryRun = false) {
|
|
|
2354
2366
|
p4.log.success(`jorgex-stack: v${localVersion} \u2014 al d\xEDa.`);
|
|
2355
2367
|
} else {
|
|
2356
2368
|
stackNeedsUpdate = true;
|
|
2357
|
-
const mode =
|
|
2369
|
+
const mode = maintainer ? STACK_METHOD_CLONE : `pnpm add -g jorgex-stack@${npmLatest}`;
|
|
2358
2370
|
updateItems.push({
|
|
2359
2371
|
value: "stack",
|
|
2360
2372
|
label: `jorgex-stack: v${localVersion} \u2192 v${npmLatest}`,
|
|
@@ -2406,6 +2418,11 @@ async function runInteractiveUpdate(localVersion, yes, dryRun = false) {
|
|
|
2406
2418
|
p4.log.success(`${repo}: al d\xEDa (pin ${pinned.slice(0, 7)}). Skills: ${names.join(", ")}`);
|
|
2407
2419
|
}
|
|
2408
2420
|
}
|
|
2421
|
+
if (!maintainer) {
|
|
2422
|
+
p4.log.info(
|
|
2423
|
+
"Skills de terceros: pineadas con esta versi\xF3n del stack \u2014 su revisi\xF3n upstream se hace desde el clon del repo."
|
|
2424
|
+
);
|
|
2425
|
+
}
|
|
2409
2426
|
const skillUpdates = buildEligibleSkillUpdates(typedSkillHeads);
|
|
2410
2427
|
for (const skillInfo of skillUpdates) {
|
|
2411
2428
|
const modifiedWarning = skillInfo.modified ? " \u26A0 modificada localmente" : "";
|
package/package.json
CHANGED
package/upstreams.json
CHANGED
|
@@ -23,20 +23,15 @@
|
|
|
23
23
|
},
|
|
24
24
|
"diagnose": {
|
|
25
25
|
"source": "github:mattpocock/skills",
|
|
26
|
-
"path": "skills/engineering/
|
|
27
|
-
"commit": "694fa30311e02c2639942308513555e61ee84a6f"
|
|
26
|
+
"path": "skills/engineering/diagnosing-bugs",
|
|
27
|
+
"commit": "694fa30311e02c2639942308513555e61ee84a6f",
|
|
28
|
+
"note": "upstream renombró la carpeta diagnose → diagnosing-bugs; mantenemos el nombre local 'diagnose'. El pin sigue en la última revisión aceptada hasta hacer diff y re-pin deliberado del contenido nuevo."
|
|
28
29
|
},
|
|
29
30
|
"find-skills": {
|
|
30
31
|
"source": "github:vercel-labs/skills",
|
|
31
32
|
"path": "skills/find-skills",
|
|
32
33
|
"commit": "be0dd25b4a8665894a56f45ef582cc02ca802c39"
|
|
33
34
|
},
|
|
34
|
-
"graphify": {
|
|
35
|
-
"source": "github:safishamsi/graphify",
|
|
36
|
-
"kind": "release",
|
|
37
|
-
"version": "0.7.16",
|
|
38
|
-
"commit": "cce26730212baab6d92ce5f390ef5aae56268f31"
|
|
39
|
-
},
|
|
40
35
|
"mcp-builder": {
|
|
41
36
|
"source": "github:anthropics/skills",
|
|
42
37
|
"path": "skills/mcp-builder",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
0.7.16
|