@monoes/monomindcli 2.15.7 → 2.16.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/.claude/helpers/build-skill-registry.cjs +23 -2
- package/.claude/helpers/handlers/route-handler.cjs +89 -3
- package/.claude/helpers/handlers/session-restore-handler.cjs +1 -1
- package/.claude/helpers/jev-picker.cjs +499 -0
- package/.claude/helpers/redact-secrets.cjs +69 -0
- package/.claude/skills/mastermind-agent-select/SKILL.md +28 -0
- package/dist/src/catalog/blueprints.d.ts +39 -0
- package/dist/src/catalog/blueprints.d.ts.map +1 -0
- package/dist/src/catalog/blueprints.js +78 -0
- package/dist/src/catalog/blueprints.js.map +1 -0
- package/dist/src/catalog/digest.d.ts +16 -0
- package/dist/src/catalog/digest.d.ts.map +1 -0
- package/dist/src/catalog/digest.js +62 -0
- package/dist/src/catalog/digest.js.map +1 -0
- package/dist/src/catalog/frontmatter.d.ts +23 -0
- package/dist/src/catalog/frontmatter.d.ts.map +1 -0
- package/dist/src/catalog/frontmatter.js +80 -0
- package/dist/src/catalog/frontmatter.js.map +1 -0
- package/dist/src/catalog/lifecycle.d.ts +31 -0
- package/dist/src/catalog/lifecycle.d.ts.map +1 -0
- package/dist/src/catalog/lifecycle.js +78 -0
- package/dist/src/catalog/lifecycle.js.map +1 -0
- package/dist/src/catalog/projection.d.ts +57 -0
- package/dist/src/catalog/projection.d.ts.map +1 -0
- package/dist/src/catalog/projection.js +272 -0
- package/dist/src/catalog/projection.js.map +1 -0
- package/dist/src/catalog/scan.d.ts +37 -0
- package/dist/src/catalog/scan.d.ts.map +1 -0
- package/dist/src/catalog/scan.js +214 -0
- package/dist/src/catalog/scan.js.map +1 -0
- package/dist/src/catalog/snapshot.d.ts +62 -0
- package/dist/src/catalog/snapshot.d.ts.map +1 -0
- package/dist/src/catalog/snapshot.js +183 -0
- package/dist/src/catalog/snapshot.js.map +1 -0
- package/dist/src/catalog/stage.d.ts +26 -0
- package/dist/src/catalog/stage.d.ts.map +1 -0
- package/dist/src/catalog/stage.js +316 -0
- package/dist/src/catalog/stage.js.map +1 -0
- package/dist/src/catalog/state.d.ts +23 -0
- package/dist/src/catalog/state.d.ts.map +1 -0
- package/dist/src/catalog/state.js +102 -0
- package/dist/src/catalog/state.js.map +1 -0
- package/dist/src/catalog/types.d.ts +289 -0
- package/dist/src/catalog/types.d.ts.map +1 -0
- package/dist/src/catalog/types.js +118 -0
- package/dist/src/catalog/types.js.map +1 -0
- package/dist/src/commands/catalog.d.ts +14 -0
- package/dist/src/commands/catalog.d.ts.map +1 -0
- package/dist/src/commands/catalog.js +392 -0
- package/dist/src/commands/catalog.js.map +1 -0
- package/dist/src/commands/doctor-catalog-checks.d.ts +3 -0
- package/dist/src/commands/doctor-catalog-checks.d.ts.map +1 -0
- package/dist/src/commands/doctor-catalog-checks.js +69 -0
- package/dist/src/commands/doctor-catalog-checks.js.map +1 -0
- package/dist/src/commands/doctor-decision-checks.d.ts +10 -0
- package/dist/src/commands/doctor-decision-checks.d.ts.map +1 -0
- package/dist/src/commands/doctor-decision-checks.js +82 -0
- package/dist/src/commands/doctor-decision-checks.js.map +1 -0
- package/dist/src/commands/doctor.d.ts.map +1 -1
- package/dist/src/commands/doctor.js +9 -1
- package/dist/src/commands/doctor.js.map +1 -1
- package/dist/src/commands/index.d.ts +2 -2
- package/dist/src/commands/index.d.ts.map +1 -1
- package/dist/src/commands/index.js +4 -1
- package/dist/src/commands/index.js.map +1 -1
- package/dist/src/commands/org-observe.d.ts.map +1 -1
- package/dist/src/commands/org-observe.js +7 -1
- package/dist/src/commands/org-observe.js.map +1 -1
- package/dist/src/commands/org-skills.d.ts.map +1 -1
- package/dist/src/commands/org-skills.js +14 -4
- package/dist/src/commands/org-skills.js.map +1 -1
- package/dist/src/commands/org.d.ts.map +1 -1
- package/dist/src/commands/org.js +8 -1
- package/dist/src/commands/org.js.map +1 -1
- package/dist/src/commands/pick.d.ts +4 -0
- package/dist/src/commands/pick.d.ts.map +1 -0
- package/dist/src/commands/pick.js +77 -0
- package/dist/src/commands/pick.js.map +1 -0
- package/dist/src/commands/route.js +1 -1
- package/dist/src/commands/route.js.map +1 -1
- package/dist/src/decision/catalogs.d.ts +20 -0
- package/dist/src/decision/catalogs.d.ts.map +1 -0
- package/dist/src/decision/catalogs.js +64 -0
- package/dist/src/decision/catalogs.js.map +1 -0
- package/dist/src/decision/jev.d.ts +85 -0
- package/dist/src/decision/jev.d.ts.map +1 -0
- package/dist/src/decision/jev.js +72 -0
- package/dist/src/decision/jev.js.map +1 -0
- package/dist/src/decision/picks.d.ts +50 -0
- package/dist/src/decision/picks.d.ts.map +1 -0
- package/dist/src/decision/picks.js +100 -0
- package/dist/src/decision/picks.js.map +1 -0
- package/dist/src/init/helpers-generator.d.ts.map +1 -1
- package/dist/src/init/helpers-generator.js +7 -0
- package/dist/src/init/helpers-generator.js.map +1 -1
- package/dist/src/orgrt/checkpoint-ops.d.ts.map +1 -1
- package/dist/src/orgrt/checkpoint-ops.js +6 -1
- package/dist/src/orgrt/checkpoint-ops.js.map +1 -1
- package/dist/src/orgrt/daemon.d.ts +14 -1
- package/dist/src/orgrt/daemon.d.ts.map +1 -1
- package/dist/src/orgrt/daemon.js +32 -3
- package/dist/src/orgrt/daemon.js.map +1 -1
- package/dist/src/orgrt/decisions.d.ts +7 -0
- package/dist/src/orgrt/decisions.d.ts.map +1 -1
- package/dist/src/orgrt/decisions.js +60 -14
- package/dist/src/orgrt/decisions.js.map +1 -1
- package/dist/src/orgrt/session.d.ts +6 -0
- package/dist/src/orgrt/session.d.ts.map +1 -1
- package/dist/src/orgrt/session.js +18 -1
- package/dist/src/orgrt/session.js.map +1 -1
- package/dist/src/orgrt/skill-library.d.ts +10 -1
- package/dist/src/orgrt/skill-library.d.ts.map +1 -1
- package/dist/src/orgrt/skill-library.js +53 -4
- package/dist/src/orgrt/skill-library.js.map +1 -1
- package/dist/src/orgrt/types.d.ts +2 -0
- package/dist/src/orgrt/types.d.ts.map +1 -1
- package/dist/src/orgrt/types.js +4 -0
- package/dist/src/orgrt/types.js.map +1 -1
- package/dist/src/platform-adapters/mutation.d.ts +34 -0
- package/dist/src/platform-adapters/mutation.d.ts.map +1 -0
- package/dist/src/platform-adapters/mutation.js +188 -0
- package/dist/src/platform-adapters/mutation.js.map +1 -0
- package/dist/src/platform-adapters/operations.d.ts +7 -1
- package/dist/src/platform-adapters/operations.d.ts.map +1 -1
- package/dist/src/platform-adapters/operations.js +18 -76
- package/dist/src/platform-adapters/operations.js.map +1 -1
- package/dist/src/routing/jev-step.d.ts +17 -0
- package/dist/src/routing/jev-step.d.ts.map +1 -0
- package/dist/src/routing/jev-step.js +27 -0
- package/dist/src/routing/jev-step.js.map +1 -0
- package/dist/src/routing/route-layer-factory.d.ts.map +1 -1
- package/dist/src/routing/route-layer-factory.js +16 -1
- package/dist/src/routing/route-layer-factory.js.map +1 -1
- package/dist/src/utils/redaction.d.ts.map +1 -1
- package/dist/src/utils/redaction.js +19 -4
- package/dist/src/utils/redaction.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
/**
|
|
3
|
+
* Secret redaction for text that leaves the machine (jev-picker.cjs masks the
|
|
4
|
+
* task and candidate descriptions with it before a decision-model request).
|
|
5
|
+
*/
|
|
6
|
+
// Ported VERBATIM from packages/@monomind/cli/src/utils/redaction.ts SECRET_PATTERNS
|
|
7
|
+
// (the maintained redactor: JSON keys, header bearer tokens, fine-grained GitHub,
|
|
8
|
+
// GitLab, Slack, Stripe, JWT, credentialed URLs, AWS/Google keys, Basic auth,
|
|
9
|
+
// env passwords). A test compares the two lists source-for-source, so an edit to
|
|
10
|
+
// one without the other fails CI.
|
|
11
|
+
var SECRET_PATTERNS = [
|
|
12
|
+
/(?:api[_-]?key|apikey)['"]?\s*[:=]\s*['"]?[^\s'"]{8,}['"]?/gi,
|
|
13
|
+
/(?:secret|password|passwd|pwd)['"]?\s*[:=]\s*['"]?[^\s'"]{8,}['"]?/gi,
|
|
14
|
+
/(?:token|bearer)['"]?\s*[:=]\s*['"]?[^\s'"]{10,}['"]?/gi,
|
|
15
|
+
/\bbearer\s+['"]?[^\s'"]{10,}['"]?/gi,
|
|
16
|
+
/-----BEGIN (?:RSA |EC |DSA |OPENSSH |ENCRYPTED |PGP )?PRIVATE KEY(?: BLOCK)?-----(?:[^-]|-(?!----))*-----END (?:RSA |EC |DSA |OPENSSH |ENCRYPTED |PGP )?PRIVATE KEY(?: BLOCK)?-----/g,
|
|
17
|
+
/sk-ant-[a-zA-Z0-9_-]{20,}/g,
|
|
18
|
+
/sk-[a-zA-Z0-9_-]{20,}/g,
|
|
19
|
+
/gh[pousr]_[A-Za-z0-9]{20,}/g,
|
|
20
|
+
/github_pat_[A-Za-z0-9_]{20,}/g,
|
|
21
|
+
/glpat-[A-Za-z0-9_-]{16,}/g,
|
|
22
|
+
/xox[abprs]-[A-Za-z0-9-]{10,}/g,
|
|
23
|
+
/xapp-[A-Za-z0-9-]{10,}/g,
|
|
24
|
+
/hf_[A-Za-z0-9]{30,}/g,
|
|
25
|
+
/ya29\.[A-Za-z0-9_-]{20,}/g,
|
|
26
|
+
/[rs]k_(?:live|test)_[A-Za-z0-9]{16,}/g,
|
|
27
|
+
/npm_[A-Za-z0-9]{20,}/g,
|
|
28
|
+
/AKIA[0-9A-Z]{16}/g,
|
|
29
|
+
/(?<![a-zA-Z0-9_-])eyJ[a-zA-Z0-9_-]{10,}\.[a-zA-Z0-9_-]{10,}\.[a-zA-Z0-9_-]{10,}/g,
|
|
30
|
+
/[a-zA-Z][a-zA-Z0-9+.-]{0,31}:\/\/[^:\s]{1,256}:[^@\s]{1,256}@[^\s'"]+/g,
|
|
31
|
+
/aws_?secret_?access_?key['"]?\s*[:=]\s*['"]?[A-Za-z0-9/+=]{40}['"]?/gi,
|
|
32
|
+
/AIza[0-9A-Za-z_-]{35}/g,
|
|
33
|
+
/\bauthorization['"]?\s*[:=]\s*['"]?basic\s+[A-Za-z0-9+/]+={0,2}/gi,
|
|
34
|
+
/\b(?:[A-Z0-9]+_)*(?:PASS|PASSWORD|PASSWD|PWD)\s*=\s*['"]?[^\s'"]+['"]?/g,
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
/** Mask credential-shaped text before it leaves the machine — same output as redaction.ts redactSecrets. */
|
|
38
|
+
function redactSecrets(text) {
|
|
39
|
+
var out = String(text || '');
|
|
40
|
+
SECRET_PATTERNS.forEach(function (re) {
|
|
41
|
+
out = out.replace(re, '[redacted]');
|
|
42
|
+
});
|
|
43
|
+
return out;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Text is cut to this before redaction, so the synchronous regex pass stays short;
|
|
47
|
+
// the margin over the 8000-char Jev state keeps a secret straddling that final
|
|
48
|
+
// cut (a PEM block is a few KB) whole.
|
|
49
|
+
var REDACT_WINDOW_CHARS = 16000;
|
|
50
|
+
|
|
51
|
+
/** redactSecrets over the first REDACT_WINDOW_CHARS of `text` only. */
|
|
52
|
+
function redactHead(text) {
|
|
53
|
+
var s = String(text || '');
|
|
54
|
+
var head = s.slice(0, REDACT_WINDOW_CHARS);
|
|
55
|
+
if (s.length > REDACT_WINDOW_CHARS) {
|
|
56
|
+
// A secret cut at the window edge no longer matches its pattern, and earlier
|
|
57
|
+
// secrets shrinking to "[redacted]" pull it into the sent text: drop the cut
|
|
58
|
+
// token (a scan, not /\S+$/, which is quadratic) and a key block without a whole
|
|
59
|
+
// END line (a cut `-----END RSA ` does not close it).
|
|
60
|
+
var end = head.length;
|
|
61
|
+
while (end > 0 && !/\s/.test(head.charAt(end - 1))) end--;
|
|
62
|
+
head = head.slice(0, end);
|
|
63
|
+
var begin = head.lastIndexOf('-----BEGIN ');
|
|
64
|
+
if (begin !== -1 && !/-----END [^-\r\n]*-----/.test(head.slice(begin))) head = head.slice(0, begin);
|
|
65
|
+
}
|
|
66
|
+
return redactSecrets(head);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
module.exports = { SECRET_PATTERNS: SECRET_PATTERNS, redactSecrets: redactSecrets, redactHead: redactHead };
|
|
@@ -22,6 +22,22 @@ Use this pattern whenever a mastermind skill needs to select specialist agents.
|
|
|
22
22
|
|
|
23
23
|
REGISTRY="${REGISTRY:-.monomind/registry.json}"
|
|
24
24
|
|
|
25
|
+
# 0. Decision model first. `monomind pick` asks Jev/OpenJev when configured
|
|
26
|
+
# (MONOMIND_JEV_URL, or TYPESAFE_API_KEY + MONOMIND_JEV_HOSTED=1) and
|
|
27
|
+
# otherwise ranks by keywords.
|
|
28
|
+
# Local only — never npx (no registry egress). A globally installed monomind may
|
|
29
|
+
# predate `pick`, so each candidate must prove it supports the command.
|
|
30
|
+
mm() { for c in monomind ./node_modules/.bin/monomind; do
|
|
31
|
+
command -v "$c" >/dev/null 2>&1 || [ -x "$c" ] || continue
|
|
32
|
+
"$c" pick --help >/dev/null 2>&1 && { "$c" "$@"; return $?; }
|
|
33
|
+
done; return 127; }
|
|
34
|
+
selected_agents=$(mm pick -t "$PROMPT" --agents --categories "$CATEGORIES" \
|
|
35
|
+
--top "$TOP_N" --json 2>/dev/null \
|
|
36
|
+
| jq -c '[.agents.ranked[] | {name: (.name // .id), slug: .id, category}]' 2>/dev/null)
|
|
37
|
+
|
|
38
|
+
# Fallback when the CLI is unavailable: the registry keyword scorer below.
|
|
39
|
+
if [ -z "$selected_agents" ] || [ "$selected_agents" = "[]" ]; then
|
|
40
|
+
|
|
25
41
|
# 1. Extract candidates from the registry filtered by category
|
|
26
42
|
candidates=$(jq -r \
|
|
27
43
|
--arg cats "$CATEGORIES" \
|
|
@@ -58,6 +74,7 @@ selected_agents=$(echo "$candidates" | jq -Rs \
|
|
|
58
74
|
.[0:$n] |
|
|
59
75
|
map(.agent)
|
|
60
76
|
')
|
|
77
|
+
fi
|
|
61
78
|
|
|
62
79
|
echo "$selected_agents"
|
|
63
80
|
```
|
|
@@ -92,6 +109,16 @@ The output is a JSON array of `{name, slug, category}` objects. Use `.name` as t
|
|
|
92
109
|
TASK_DESC="<one-line description of what this agent must do>"
|
|
93
110
|
CATS="engineering development"
|
|
94
111
|
|
|
112
|
+
# Local only — never npx (no registry egress). A globally installed monomind may
|
|
113
|
+
# predate `pick`, so each candidate must prove it supports the command.
|
|
114
|
+
mm() { for c in monomind ./node_modules/.bin/monomind; do
|
|
115
|
+
command -v "$c" >/dev/null 2>&1 || [ -x "$c" ] || continue
|
|
116
|
+
"$c" pick --help >/dev/null 2>&1 && { "$c" "$@"; return $?; }
|
|
117
|
+
done; return 127; }
|
|
118
|
+
best_agent=$(mm pick -t "$TASK_DESC" --agents --categories "$CATS" --top 1 --json 2>/dev/null \
|
|
119
|
+
| jq -r '.agents.ranked[0].name // .agents.ranked[0].id // empty' 2>/dev/null)
|
|
120
|
+
|
|
121
|
+
if [ -z "$best_agent" ]; then
|
|
95
122
|
best_agent=$(jq -r \
|
|
96
123
|
--arg cats "$CATS" \
|
|
97
124
|
--arg task "$(echo "$TASK_DESC" | tr '[:upper:]' '[:lower:]')" \
|
|
@@ -104,6 +131,7 @@ best_agent=$(jq -r \
|
|
|
104
131
|
| sort_by(-.score)
|
|
105
132
|
| .[0].name // "coder"' \
|
|
106
133
|
"$REGISTRY")
|
|
134
|
+
fi
|
|
107
135
|
```
|
|
108
136
|
|
|
109
137
|
---
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { OrgDef } from '../orgrt/types.js';
|
|
3
|
+
export declare const BlueprintSchema: z.ZodObject<{
|
|
4
|
+
name: z.ZodString;
|
|
5
|
+
description: z.ZodString;
|
|
6
|
+
archetype: z.ZodOptional<z.ZodString>;
|
|
7
|
+
skills: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
8
|
+
skill_pool: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
9
|
+
runtimeHints: z.ZodOptional<z.ZodObject<{
|
|
10
|
+
reasoning: z.ZodOptional<z.ZodEnum<{
|
|
11
|
+
high: "high";
|
|
12
|
+
low: "low";
|
|
13
|
+
medium: "medium";
|
|
14
|
+
}>>;
|
|
15
|
+
}, z.core.$strict>>;
|
|
16
|
+
recommendedPolicy: z.ZodOptional<z.ZodObject<{
|
|
17
|
+
git: z.ZodOptional<z.ZodEnum<{
|
|
18
|
+
commit: "commit";
|
|
19
|
+
none: "none";
|
|
20
|
+
push: "push";
|
|
21
|
+
read: "read";
|
|
22
|
+
}>>;
|
|
23
|
+
}, z.core.$strict>>;
|
|
24
|
+
}, z.core.$strict>;
|
|
25
|
+
export type Blueprint = z.infer<typeof BlueprintSchema>;
|
|
26
|
+
export interface ResolvedBlueprints {
|
|
27
|
+
def: OrgDef;
|
|
28
|
+
errors: string[];
|
|
29
|
+
notes: string[];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Fills each blueprint role's unset `skills` / `skill_pool` from its active
|
|
33
|
+
* `org` blueprint. Explicit role fields always win; blueprints never produce
|
|
34
|
+
* `policy` or `tool_providers` — their hints only become `notes`. Returns the
|
|
35
|
+
* input object itself when no role names a blueprint, and never writes the
|
|
36
|
+
* Org JSON. Skill names are left to the existing `validateRoleSkills`.
|
|
37
|
+
*/
|
|
38
|
+
export declare function resolveOrgDefBlueprints(def: OrgDef, root: string): ResolvedBlueprints;
|
|
39
|
+
//# sourceMappingURL=blueprints.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blueprints.d.ts","sourceRoot":"","sources":["../../../src/catalog/blueprints.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAKhD,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;kBAmBjB,CAAC;AAEZ,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAcD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,kBAAkB,CA6BrF"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { verifyEntry } from './digest.js';
|
|
5
|
+
import { buildSnapshot, eligible } from './snapshot.js';
|
|
6
|
+
import { CATALOG_NAME_RE } from './types.js';
|
|
7
|
+
export const BlueprintSchema = z
|
|
8
|
+
.object({
|
|
9
|
+
name: z.string().regex(CATALOG_NAME_RE),
|
|
10
|
+
description: z.string().min(1).max(500),
|
|
11
|
+
archetype: z.string().regex(CATALOG_NAME_RE).optional(),
|
|
12
|
+
skills: z.array(z.string().regex(CATALOG_NAME_RE)).max(20).default([]),
|
|
13
|
+
skill_pool: z
|
|
14
|
+
.array(z.string().regex(/^(tag:)?[a-z0-9][a-z0-9-]{0,63}$/))
|
|
15
|
+
.max(50)
|
|
16
|
+
.default([]),
|
|
17
|
+
runtimeHints: z
|
|
18
|
+
.object({ reasoning: z.enum(['low', 'medium', 'high']).optional() })
|
|
19
|
+
.strict()
|
|
20
|
+
.optional(),
|
|
21
|
+
recommendedPolicy: z
|
|
22
|
+
.object({ git: z.enum(['none', 'read', 'commit', 'push']).optional() })
|
|
23
|
+
.strict()
|
|
24
|
+
.optional(),
|
|
25
|
+
})
|
|
26
|
+
.strict();
|
|
27
|
+
/** Active `org` blueprint by name, parsed from its verified package. */
|
|
28
|
+
function loadBlueprint(root, name) {
|
|
29
|
+
const asset = eligible(buildSnapshot(root), 'org').find((a) => a.kind === 'blueprint' && a.name === name);
|
|
30
|
+
if (!asset?.dir)
|
|
31
|
+
return undefined;
|
|
32
|
+
// The snapshot may be cached; the bytes read below must still match the digest.
|
|
33
|
+
const check = verifyEntry(root, asset);
|
|
34
|
+
if (!check.ok)
|
|
35
|
+
throw new Error(`package ${check.reason}`);
|
|
36
|
+
return BlueprintSchema.parse(JSON.parse(readFileSync(join(check.dir, 'blueprint.json'), 'utf8')));
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Fills each blueprint role's unset `skills` / `skill_pool` from its active
|
|
40
|
+
* `org` blueprint. Explicit role fields always win; blueprints never produce
|
|
41
|
+
* `policy` or `tool_providers` — their hints only become `notes`. Returns the
|
|
42
|
+
* input object itself when no role names a blueprint, and never writes the
|
|
43
|
+
* Org JSON. Skill names are left to the existing `validateRoleSkills`.
|
|
44
|
+
*/
|
|
45
|
+
export function resolveOrgDefBlueprints(def, root) {
|
|
46
|
+
if (!def.roles.some((r) => r.blueprint !== undefined))
|
|
47
|
+
return { def, errors: [], notes: [] };
|
|
48
|
+
const errors = [];
|
|
49
|
+
const notes = [];
|
|
50
|
+
const roles = def.roles.map((role) => {
|
|
51
|
+
if (role.blueprint === undefined)
|
|
52
|
+
return role;
|
|
53
|
+
const label = `role "${role.id}": blueprint "${role.blueprint}"`;
|
|
54
|
+
let bp;
|
|
55
|
+
try {
|
|
56
|
+
bp = loadBlueprint(root, role.blueprint);
|
|
57
|
+
}
|
|
58
|
+
catch (e) {
|
|
59
|
+
errors.push(`${label} is invalid: ${e.message}`);
|
|
60
|
+
return role;
|
|
61
|
+
}
|
|
62
|
+
if (!bp) {
|
|
63
|
+
errors.push(`${label} is not active for org on this machine`);
|
|
64
|
+
return role;
|
|
65
|
+
}
|
|
66
|
+
if (bp.runtimeHints?.reasoning)
|
|
67
|
+
notes.push(`${label} suggests reasoning "${bp.runtimeHints.reasoning}" (not applied)`);
|
|
68
|
+
if (bp.recommendedPolicy?.git)
|
|
69
|
+
notes.push(`${label} recommends policy.git "${bp.recommendedPolicy.git}" (not applied)`);
|
|
70
|
+
return {
|
|
71
|
+
...role,
|
|
72
|
+
skills: role.skills ?? [...(bp.archetype ? [bp.archetype] : []), ...bp.skills],
|
|
73
|
+
skill_pool: role.skill_pool ?? bp.skill_pool,
|
|
74
|
+
};
|
|
75
|
+
});
|
|
76
|
+
return { def: { ...def, roles }, errors, notes };
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=blueprints.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blueprints.js","sourceRoot":"","sources":["../../../src/catalog/blueprints.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { CatalogEntry } from './types.js';
|
|
2
|
+
export declare const catalogDir: (root: string) => string;
|
|
3
|
+
export declare const packagesDir: (root: string) => string;
|
|
4
|
+
/** sha256 over (u32 pathLen, path, u64 byteLen, bytes) for every file, paths sorted by code unit. */
|
|
5
|
+
export declare function packageDigest(dir: string): string;
|
|
6
|
+
/** `<packages>/<name>/<sha12>`, proven to stay inside the store after realpath. */
|
|
7
|
+
export declare function resolvePackageDir(root: string, entry: Pick<CatalogEntry, 'id' | 'sha256'>): string;
|
|
8
|
+
export type DigestCheck = {
|
|
9
|
+
ok: true;
|
|
10
|
+
dir: string;
|
|
11
|
+
} | {
|
|
12
|
+
ok: false;
|
|
13
|
+
reason: 'missing-package' | 'digest-mismatch' | 'escaping-path';
|
|
14
|
+
};
|
|
15
|
+
export declare function verifyEntry(root: string, entry: Pick<CatalogEntry, 'id' | 'sha256'>): DigestCheck;
|
|
16
|
+
//# sourceMappingURL=digest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"digest.d.ts","sourceRoot":"","sources":["../../../src/catalog/digest.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,eAAO,MAAM,UAAU,SAAU,MAAM,KAAG,MAA4C,CAAC;AACvF,eAAO,MAAM,WAAW,SAAU,MAAM,KAAG,MAA4C,CAAC;AAaxF,qGAAqG;AACrG,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAWjD;AAED,mFAAmF;AACnF,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,GAAG,QAAQ,CAAC,GACzC,MAAM,CAQR;AAED,MAAM,MAAM,WAAW,GACnB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACzB;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,iBAAiB,GAAG,iBAAiB,GAAG,eAAe,CAAA;CAAE,CAAC;AAEnF,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,GAAG,QAAQ,CAAC,GAAG,WAAW,CAiBjG"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { lstatSync, readdirSync, readFileSync, realpathSync } from 'node:fs';
|
|
3
|
+
import { join, relative, sep } from 'node:path';
|
|
4
|
+
export const catalogDir = (root) => join(root, '.monomind', 'catalog');
|
|
5
|
+
export const packagesDir = (root) => join(catalogDir(root), 'packages');
|
|
6
|
+
function files(dir, prefix = '') {
|
|
7
|
+
const out = [];
|
|
8
|
+
for (const e of readdirSync(join(dir, prefix), { withFileTypes: true })) {
|
|
9
|
+
const rel = prefix ? `${prefix}/${e.name}` : e.name;
|
|
10
|
+
if (e.isSymbolicLink())
|
|
11
|
+
throw new Error(`symlink in package: ${rel}`);
|
|
12
|
+
if (e.isDirectory())
|
|
13
|
+
out.push(...files(dir, rel));
|
|
14
|
+
else if (e.isFile())
|
|
15
|
+
out.push(rel);
|
|
16
|
+
}
|
|
17
|
+
return out;
|
|
18
|
+
}
|
|
19
|
+
/** sha256 over (u32 pathLen, path, u64 byteLen, bytes) for every file, paths sorted by code unit. */
|
|
20
|
+
export function packageDigest(dir) {
|
|
21
|
+
const h = createHash('sha256');
|
|
22
|
+
for (const rel of files(dir).sort()) {
|
|
23
|
+
const bytes = readFileSync(join(dir, rel));
|
|
24
|
+
const p = Buffer.from(rel, 'utf8');
|
|
25
|
+
const lens = Buffer.alloc(12);
|
|
26
|
+
lens.writeUInt32BE(p.length, 0);
|
|
27
|
+
lens.writeBigUInt64BE(BigInt(bytes.length), 4);
|
|
28
|
+
h.update(lens.subarray(0, 4)).update(p).update(lens.subarray(4)).update(bytes);
|
|
29
|
+
}
|
|
30
|
+
return h.digest('hex');
|
|
31
|
+
}
|
|
32
|
+
/** `<packages>/<name>/<sha12>`, proven to stay inside the store after realpath. */
|
|
33
|
+
export function resolvePackageDir(root, entry) {
|
|
34
|
+
const store = realpathSync(packagesDir(root));
|
|
35
|
+
const name = entry.id.split(':')[1] ?? '';
|
|
36
|
+
const dir = realpathSync(join(store, name, entry.sha256.slice(0, 12)));
|
|
37
|
+
const rel = relative(store, dir);
|
|
38
|
+
if (rel.startsWith('..') || rel.includes(`..${sep}`) || lstatSync(dir).isSymbolicLink())
|
|
39
|
+
throw new Error(`package path escapes the store: ${entry.id}`);
|
|
40
|
+
return dir;
|
|
41
|
+
}
|
|
42
|
+
export function verifyEntry(root, entry) {
|
|
43
|
+
let dir;
|
|
44
|
+
try {
|
|
45
|
+
dir = resolvePackageDir(root, entry);
|
|
46
|
+
}
|
|
47
|
+
catch (e) {
|
|
48
|
+
return {
|
|
49
|
+
ok: false,
|
|
50
|
+
reason: String(e).includes('escapes') ? 'escaping-path' : 'missing-package',
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
return packageDigest(dir) === entry.sha256
|
|
55
|
+
? { ok: true, dir }
|
|
56
|
+
: { ok: false, reason: 'digest-mismatch' };
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return { ok: false, reason: 'digest-mismatch' };
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=digest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"digest.js","sourceRoot":"","sources":["../../../src/catalog/digest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** The only top-level frontmatter keys a catalog SKILL.md may carry. */
|
|
2
|
+
export declare const ALLOWED_FRONTMATTER_KEYS: readonly ['name', 'description', 'tags', 'tools', 'license'];
|
|
3
|
+
/**
|
|
4
|
+
* Problems that keep `text` from being a canonical catalog SKILL.md: no
|
|
5
|
+
* frontmatter, a key outside the allow-list, any line that is not a
|
|
6
|
+
* single-line `key: value` (indented, flow-mapping, anchor, alias, tag or
|
|
7
|
+
* block-scalar forms, or a value holding a U+2028/U+2029), or a `---`
|
|
8
|
+
* anywhere in a line — Claude Code ends the frontmatter at the first `---`,
|
|
9
|
+
* even mid-value, and would read the rest as body. Staging refuses what
|
|
10
|
+
* `sanitizeFrontmatter` produces unless this is empty.
|
|
11
|
+
*/
|
|
12
|
+
export declare function frontmatterViolations(text: string): string[];
|
|
13
|
+
/**
|
|
14
|
+
* Rewrites the frontmatter of `text` to the allow-listed keys, one line each
|
|
15
|
+
* (strings JSON-quoted, lists as JSON arrays of plain tokens), keeping the
|
|
16
|
+
* body byte-for-byte. `removed` names the dropped keys. Text without
|
|
17
|
+
* frontmatter is returned unchanged (inspection then refuses it).
|
|
18
|
+
*/
|
|
19
|
+
export declare function sanitizeFrontmatter(text: string): {
|
|
20
|
+
text: string;
|
|
21
|
+
removed: string[];
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=frontmatter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontmatter.d.ts","sourceRoot":"","sources":["../../../src/catalog/frontmatter.ts"],"names":[],"mappings":"AAQA,wEAAwE;AACxE,eAAO,MAAM,wBAAwB,YACnC,MAAM,EACN,aAAa,EACb,MAAM,EACN,OAAO,EACP,SAAS,CACD,CAAC;AAOX;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAc5D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAqBrF"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SKILL.md frontmatter allow-list. Platforms read execution config from the
|
|
3
|
+
* frontmatter (`hooks`, `allowed-tools`, `model`, `context`, `agent`, …), so
|
|
4
|
+
* staging rewrites it to the keys below before the package is hashed, and
|
|
5
|
+
* projection re-checks the stored bytes with `frontmatterViolations`.
|
|
6
|
+
*/
|
|
7
|
+
import { parseFrontmatter } from '../orgrt/skill-library.js';
|
|
8
|
+
/** The only top-level frontmatter keys a catalog SKILL.md may carry. */
|
|
9
|
+
export const ALLOWED_FRONTMATTER_KEYS = [
|
|
10
|
+
'name',
|
|
11
|
+
'description',
|
|
12
|
+
'tags',
|
|
13
|
+
'tools',
|
|
14
|
+
'license',
|
|
15
|
+
];
|
|
16
|
+
const FRONTMATTER_RE = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
|
|
17
|
+
const LIST_ITEM_RE = /^[A-Za-z0-9_.:/-]+$/;
|
|
18
|
+
const PLAIN_NAME_RE = /^[a-z0-9][a-z0-9-]*$/;
|
|
19
|
+
const ALLOWED = ALLOWED_FRONTMATTER_KEYS;
|
|
20
|
+
/**
|
|
21
|
+
* Problems that keep `text` from being a canonical catalog SKILL.md: no
|
|
22
|
+
* frontmatter, a key outside the allow-list, any line that is not a
|
|
23
|
+
* single-line `key: value` (indented, flow-mapping, anchor, alias, tag or
|
|
24
|
+
* block-scalar forms, or a value holding a U+2028/U+2029), or a `---`
|
|
25
|
+
* anywhere in a line — Claude Code ends the frontmatter at the first `---`,
|
|
26
|
+
* even mid-value, and would read the rest as body. Staging refuses what
|
|
27
|
+
* `sanitizeFrontmatter` produces unless this is empty.
|
|
28
|
+
*/
|
|
29
|
+
export function frontmatterViolations(text) {
|
|
30
|
+
const m = FRONTMATTER_RE.exec(text);
|
|
31
|
+
if (!m)
|
|
32
|
+
return ['SKILL.md has no frontmatter'];
|
|
33
|
+
const out = [];
|
|
34
|
+
m[1].split(/\r?\n/).forEach((line, i) => {
|
|
35
|
+
if (line.trim() === '')
|
|
36
|
+
return;
|
|
37
|
+
if (line.includes('---'))
|
|
38
|
+
return void out.push(`frontmatter line ${i + 1} contains "---"`);
|
|
39
|
+
const kv = /^([A-Za-z_][\w-]*):(?: (.*))?$/.exec(line);
|
|
40
|
+
if (!kv)
|
|
41
|
+
out.push(`frontmatter line ${i + 1} is not a single-line key: value`);
|
|
42
|
+
else if (!ALLOWED.includes(kv[1]))
|
|
43
|
+
out.push(`frontmatter key "${kv[1]}" is not allowed`);
|
|
44
|
+
else if (/^[{&*!|>]/.test(kv[2] ?? ''))
|
|
45
|
+
out.push(`frontmatter key "${kv[1]}" has a non-scalar value`);
|
|
46
|
+
});
|
|
47
|
+
return out;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Rewrites the frontmatter of `text` to the allow-listed keys, one line each
|
|
51
|
+
* (strings JSON-quoted, lists as JSON arrays of plain tokens), keeping the
|
|
52
|
+
* body byte-for-byte. `removed` names the dropped keys. Text without
|
|
53
|
+
* frontmatter is returned unchanged (inspection then refuses it).
|
|
54
|
+
*/
|
|
55
|
+
export function sanitizeFrontmatter(text) {
|
|
56
|
+
const m = FRONTMATTER_RE.exec(text);
|
|
57
|
+
if (!m)
|
|
58
|
+
return { text, removed: [] };
|
|
59
|
+
const { data, body } = parseFrontmatter(text);
|
|
60
|
+
const topLevel = m[1].split(/\r?\n/).filter((l) => /^[^\s#]/.test(l));
|
|
61
|
+
const keys = topLevel.map((l) => l.split(':')[0].trim().slice(0, 40));
|
|
62
|
+
const removed = [...new Set(keys.filter((k) => !ALLOWED.includes(k)))];
|
|
63
|
+
const q = JSON.stringify;
|
|
64
|
+
const str = (v) => (Array.isArray(v) ? v.join(' ') : v);
|
|
65
|
+
const list = (v) => (Array.isArray(v) ? v : v.split(/[,\s]+/)).filter((s) => LIST_ITEM_RE.test(s));
|
|
66
|
+
const lines = [];
|
|
67
|
+
for (const key of ALLOWED_FRONTMATTER_KEYS) {
|
|
68
|
+
const v = data[key];
|
|
69
|
+
if (v === undefined)
|
|
70
|
+
continue;
|
|
71
|
+
if (key === 'tags' || key === 'tools')
|
|
72
|
+
lines.push(`${key}: ${q(list(v))}`);
|
|
73
|
+
else if (key === 'name' && typeof v === 'string' && PLAIN_NAME_RE.test(v))
|
|
74
|
+
lines.push(`name: ${v}`);
|
|
75
|
+
else
|
|
76
|
+
lines.push(`${key}: ${q(str(v))}`);
|
|
77
|
+
}
|
|
78
|
+
return { text: ['---', ...lines, '---', ''].join('\n') + body, removed };
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=frontmatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../../../src/catalog/frontmatter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type CatalogEntry, type CatalogStatus } from './types.js';
|
|
2
|
+
export interface LifecycleOptions {
|
|
3
|
+
/** Self-asserted provenance, recorded in history. */
|
|
4
|
+
actor: string;
|
|
5
|
+
reason?: string;
|
|
6
|
+
now?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ApproveOptions extends LifecycleOptions {
|
|
9
|
+
targets: string[];
|
|
10
|
+
/** Tools to grant; must be requested by the skill and in CATALOG_GRANTABLE_TOOLS. */
|
|
11
|
+
grant?: string[];
|
|
12
|
+
replacesLegacy?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface LifecycleResult {
|
|
15
|
+
id: string;
|
|
16
|
+
before: CatalogStatus;
|
|
17
|
+
after: CatalogStatus;
|
|
18
|
+
entry: CatalogEntry;
|
|
19
|
+
}
|
|
20
|
+
/** staged → approved, recording targets, grants and legacy replacement. */
|
|
21
|
+
export declare function approve(root: string, id: string, opts: ApproveOptions): LifecycleResult;
|
|
22
|
+
/** approved or disabled → active; the package digest must verify. */
|
|
23
|
+
export declare const activate: (root: string, id: string, opts: LifecycleOptions) => LifecycleResult;
|
|
24
|
+
export declare const disable: (root: string, id: string, opts: LifecycleOptions) => LifecycleResult;
|
|
25
|
+
/** staged, active or disabled → quarantined; needs a reason. */
|
|
26
|
+
export declare const quarantine: (root: string, id: string, opts: LifecycleOptions) => LifecycleResult;
|
|
27
|
+
/** quarantined → staged; needs a reason and records `inspection.override`. */
|
|
28
|
+
export declare const release: (root: string, id: string, opts: LifecycleOptions) => LifecycleResult;
|
|
29
|
+
/** Any status but revoked → revoked (terminal); needs a reason. */
|
|
30
|
+
export declare const revoke: (root: string, id: string, opts: LifecycleOptions) => LifecycleResult;
|
|
31
|
+
//# sourceMappingURL=lifecycle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../../src/catalog/lifecycle.ts"],"names":[],"mappings":"AAMA,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,aAAa,EAGnB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,gBAAgB;IAC/B,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAe,SAAQ,gBAAgB;IACtD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,qFAAqF;IACrF,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,aAAa,CAAC;IACtB,KAAK,EAAE,aAAa,CAAC;IACrB,KAAK,EAAE,YAAY,CAAC;CACrB;AA4DD,2EAA2E;AAC3E,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,eAAe,CAcvF;AAED,qEAAqE;AACrE,eAAO,MAAM,QAAQ,SAAU,MAAM,MAAM,MAAM,QAAQ,gBAAgB,KAAG,eAC5C,CAAC;AAEjC,eAAO,MAAM,OAAO,SAAU,MAAM,MAAM,MAAM,QAAQ,gBAAgB,KAAG,eACzC,CAAC;AAEnC,gEAAgE;AAChE,eAAO,MAAM,UAAU,SAAU,MAAM,MAAM,MAAM,QAAQ,gBAAgB,KAAG,eACzC,CAAC;AAEtC,8EAA8E;AAC9E,eAAO,MAAM,OAAO,SAAU,MAAM,MAAM,MAAM,QAAQ,gBAAgB,KAAG,eAC3C,CAAC;AAEjC,mEAAmE;AACnE,eAAO,MAAM,MAAM,SAAU,MAAM,MAAM,MAAM,QAAQ,gBAAgB,KAAG,eACzC,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The mutating lifecycle verbs behind `monomind catalog approve|activate|
|
|
3
|
+
* disable|quarantine|release|revoke`. Each runs one `transition` under the
|
|
4
|
+
* catalog lock; `approve` also records targets and tool grants.
|
|
5
|
+
*/
|
|
6
|
+
import { CatalogStateError, mutateCatalogState, transition } from './state.js';
|
|
7
|
+
import { CATALOG_GRANTABLE_TOOLS, CatalogTargetSchema, } from './types.js';
|
|
8
|
+
const GRANTABLE = CATALOG_GRANTABLE_TOOLS;
|
|
9
|
+
function move(root, id, to, opts, prepare) {
|
|
10
|
+
let before;
|
|
11
|
+
let entry;
|
|
12
|
+
const now = opts.now ?? new Date().toISOString();
|
|
13
|
+
mutateCatalogState(root, (state) => {
|
|
14
|
+
const cur = state.entries.find((e) => e.id === id);
|
|
15
|
+
if (!cur)
|
|
16
|
+
throw new CatalogStateError(`no catalog entry ${id}`);
|
|
17
|
+
before = cur.status;
|
|
18
|
+
const prepared = prepare ? prepare(cur) : cur;
|
|
19
|
+
const staged = { ...state, entries: state.entries.map((e) => (e.id === id ? prepared : e)) };
|
|
20
|
+
const next = transition(staged, id, to, { actor: opts.actor, now, reason: opts.reason, root });
|
|
21
|
+
entry = next.entries.find((e) => e.id === id);
|
|
22
|
+
return next;
|
|
23
|
+
});
|
|
24
|
+
return { id, before: before, after: to, entry: entry };
|
|
25
|
+
}
|
|
26
|
+
function checkTargets(raw, kind) {
|
|
27
|
+
if (raw.length === 0)
|
|
28
|
+
throw new CatalogStateError('approve needs at least one --target');
|
|
29
|
+
const targets = raw.map((t) => {
|
|
30
|
+
const p = CatalogTargetSchema.safeParse(t);
|
|
31
|
+
if (!p.success)
|
|
32
|
+
throw new CatalogStateError(`unknown target "${t}" — use ${CatalogTargetSchema.options.join(', ')}`);
|
|
33
|
+
return p.data;
|
|
34
|
+
});
|
|
35
|
+
if (new Set(targets).size !== targets.length)
|
|
36
|
+
throw new CatalogStateError('duplicate --target');
|
|
37
|
+
if (targets.includes('jev') && !targets.includes('org'))
|
|
38
|
+
throw new CatalogStateError('the jev target requires the org target');
|
|
39
|
+
const platform = targets.find((t) => t.startsWith('platform:'));
|
|
40
|
+
if (platform && kind !== 'skill')
|
|
41
|
+
throw new CatalogStateError(`only skills can be projected; ${kind} cannot target ${platform}`);
|
|
42
|
+
return targets;
|
|
43
|
+
}
|
|
44
|
+
function checkGrants(e, grant) {
|
|
45
|
+
if (grant.length && e.kind !== 'skill')
|
|
46
|
+
throw new CatalogStateError('only skills take tool grants');
|
|
47
|
+
for (const t of grant) {
|
|
48
|
+
if (!GRANTABLE.includes(t))
|
|
49
|
+
throw new CatalogStateError(`"${t}" is not grantable — grantable tools: ${CATALOG_GRANTABLE_TOOLS.join(', ')}`);
|
|
50
|
+
if (!e.inspection.requestedTools.includes(t))
|
|
51
|
+
throw new CatalogStateError(`"${t}" is not requested by ${e.id}`);
|
|
52
|
+
}
|
|
53
|
+
return [...new Set(grant)].sort();
|
|
54
|
+
}
|
|
55
|
+
/** staged → approved, recording targets, grants and legacy replacement. */
|
|
56
|
+
export function approve(root, id, opts) {
|
|
57
|
+
return move(root, id, 'approved', opts, (e) => {
|
|
58
|
+
const targets = checkTargets(opts.targets, e.kind);
|
|
59
|
+
if (e.inspection.verdict === 'quarantine' && !e.inspection.override)
|
|
60
|
+
throw new CatalogStateError(`${id} has a quarantine inspection verdict; release it first (catalog release)`);
|
|
61
|
+
return {
|
|
62
|
+
...e,
|
|
63
|
+
targets,
|
|
64
|
+
grantedTools: checkGrants(e, opts.grant ?? []),
|
|
65
|
+
replacesLegacy: opts.replacesLegacy === true,
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/** approved or disabled → active; the package digest must verify. */
|
|
70
|
+
export const activate = (root, id, opts) => move(root, id, 'active', opts);
|
|
71
|
+
export const disable = (root, id, opts) => move(root, id, 'disabled', opts);
|
|
72
|
+
/** staged, active or disabled → quarantined; needs a reason. */
|
|
73
|
+
export const quarantine = (root, id, opts) => move(root, id, 'quarantined', opts);
|
|
74
|
+
/** quarantined → staged; needs a reason and records `inspection.override`. */
|
|
75
|
+
export const release = (root, id, opts) => move(root, id, 'staged', opts);
|
|
76
|
+
/** Any status but revoked → revoked (terminal); needs a reason. */
|
|
77
|
+
export const revoke = (root, id, opts) => move(root, id, 'revoked', opts);
|
|
78
|
+
//# sourceMappingURL=lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../../src/catalog/lifecycle.ts"],"names":[],"mappings":"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"}
|