@pleri/olam-cli 0.1.167 → 0.1.169
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/dist/commands/plans.d.ts +3 -0
- package/dist/commands/plans.d.ts.map +1 -0
- package/dist/commands/plans.js +211 -0
- package/dist/commands/plans.js.map +1 -0
- package/dist/commands/setup.d.ts +16 -0
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +70 -13
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/skills-source.d.ts +24 -0
- package/dist/commands/skills-source.d.ts.map +1 -1
- package/dist/commands/skills-source.js +169 -15
- package/dist/commands/skills-source.js.map +1 -1
- package/dist/commands/skills.d.ts +21 -0
- package/dist/commands/skills.d.ts.map +1 -1
- package/dist/commands/skills.js +44 -0
- package/dist/commands/skills.js.map +1 -1
- package/dist/image-digests.json +8 -8
- package/dist/index.js +1877 -1166
- package/dist/index.js.map +1 -1
- package/dist/lib/bootstrap-kubernetes.d.ts.map +1 -1
- package/dist/lib/bootstrap-kubernetes.js +16 -2
- package/dist/lib/bootstrap-kubernetes.js.map +1 -1
- package/dist/lib/plans-client.d.ts +69 -0
- package/dist/lib/plans-client.d.ts.map +1 -0
- package/dist/lib/plans-client.js +137 -0
- package/dist/lib/plans-client.js.map +1 -0
- package/dist/mcp-server.js +269 -32
- package/hermes-bundle/version.json +1 -1
- package/host-cp/k8s/manifests/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/auth-service/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/kg-service/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/mcp-auth-service/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/memory-service/50-deployment.yaml +1 -1
- package/host-cp/src/halt-detect.mjs +43 -0
- package/host-cp/src/panic-counter.mjs +94 -0
- package/host-cp/src/plan-chat-service.mjs +12 -1
- package/host-cp/src/server.mjs +75 -0
- package/package.json +1 -1
package/dist/mcp-server.js
CHANGED
|
@@ -11894,16 +11894,42 @@ var init_loader = __esm({
|
|
|
11894
11894
|
}
|
|
11895
11895
|
});
|
|
11896
11896
|
|
|
11897
|
+
// ../core/dist/skill-sources/source-config-schema.js
|
|
11898
|
+
var PREFIX_PATTERN, SourceConfigSchema, SourceConfigSnapshotSchema;
|
|
11899
|
+
var init_source_config_schema = __esm({
|
|
11900
|
+
"../core/dist/skill-sources/source-config-schema.js"() {
|
|
11901
|
+
"use strict";
|
|
11902
|
+
init_v3();
|
|
11903
|
+
PREFIX_PATTERN = /^[a-z0-9][a-z0-9_-]{0,38}$/;
|
|
11904
|
+
SourceConfigSchema = external_exports.object({
|
|
11905
|
+
/**
|
|
11906
|
+
* Source's RECOMMENDED rename prefix. Operators inherit this when their
|
|
11907
|
+
* `~/.olam/config.json` has no explicit `prefix` override. Same regex
|
|
11908
|
+
* shape as operator-side `SkillSourceSchema.prefix`.
|
|
11909
|
+
*/
|
|
11910
|
+
prefix: external_exports.string().regex(PREFIX_PATTERN, "source-config prefix must be ASCII lowercase + digits + dash/underscore (1-39 chars, no leading/trailing dash)").optional(),
|
|
11911
|
+
/**
|
|
11912
|
+
* Source's RECOMMENDED prefix scope. Same enum as operator-side
|
|
11913
|
+
* `SkillSourceSchema.prefixScope`. Operators inherit this when their
|
|
11914
|
+
* `~/.olam/config.json` has no explicit `prefixScope` override.
|
|
11915
|
+
*/
|
|
11916
|
+
prefixScope: external_exports.array(external_exports.enum(["skill", "agent"])).optional()
|
|
11917
|
+
}).strict();
|
|
11918
|
+
SourceConfigSnapshotSchema = SourceConfigSchema;
|
|
11919
|
+
}
|
|
11920
|
+
});
|
|
11921
|
+
|
|
11897
11922
|
// ../core/dist/skill-sources/schema.js
|
|
11898
|
-
var SKILL_SOURCE_ID_LENGTH, NAME_PATTERN, URL_PATTERN,
|
|
11923
|
+
var SKILL_SOURCE_ID_LENGTH, NAME_PATTERN, URL_PATTERN, PREFIX_PATTERN2, SkillSourceSchema;
|
|
11899
11924
|
var init_schema3 = __esm({
|
|
11900
11925
|
"../core/dist/skill-sources/schema.js"() {
|
|
11901
11926
|
"use strict";
|
|
11902
11927
|
init_v3();
|
|
11928
|
+
init_source_config_schema();
|
|
11903
11929
|
SKILL_SOURCE_ID_LENGTH = 12;
|
|
11904
11930
|
NAME_PATTERN = /^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$/;
|
|
11905
11931
|
URL_PATTERN = /^(?:https?:\/\/|git@|ssh:\/\/|file:\/\/|\/).+/;
|
|
11906
|
-
|
|
11932
|
+
PREFIX_PATTERN2 = /^[a-z0-9][a-z0-9_-]{0,38}$/;
|
|
11907
11933
|
SkillSourceSchema = external_exports.object({
|
|
11908
11934
|
id: external_exports.string().length(SKILL_SOURCE_ID_LENGTH, `skill-source id must be exactly ${SKILL_SOURCE_ID_LENGTH} chars (sha256-of-url prefix)`).regex(/^[a-f0-9]+$/, "skill-source id must be lowercase hex"),
|
|
11909
11935
|
name: external_exports.string().regex(NAME_PATTERN, "skill-source name must be ASCII lowercase + digits + dash (1-64 chars, no leading/trailing dash)"),
|
|
@@ -11920,7 +11946,7 @@ var init_schema3 = __esm({
|
|
|
11920
11946
|
* use canonical names; `olam flywheel migrate-overlays --push` enforces
|
|
11921
11947
|
* this via the reverse validator.
|
|
11922
11948
|
*/
|
|
11923
|
-
prefix: external_exports.string().regex(
|
|
11949
|
+
prefix: external_exports.string().regex(PREFIX_PATTERN2, "skill-source prefix must be ASCII lowercase + digits + dash/underscore (1-39 chars, no leading/trailing dash)").optional(),
|
|
11924
11950
|
/**
|
|
11925
11951
|
* Which artifact kinds get renamed when `prefix` is set. Optional; defaults
|
|
11926
11952
|
* to `['skill', 'agent']` for back-compat with the original Phase A semantic
|
|
@@ -11932,7 +11958,17 @@ var init_schema3 = __esm({
|
|
|
11932
11958
|
*
|
|
11933
11959
|
* NOT applicable when `prefix` is undefined.
|
|
11934
11960
|
*/
|
|
11935
|
-
prefixScope: external_exports.array(external_exports.enum(["skill", "agent"])).optional()
|
|
11961
|
+
prefixScope: external_exports.array(external_exports.enum(["skill", "agent"])).optional(),
|
|
11962
|
+
/**
|
|
11963
|
+
* Snapshot of the LAST source-config.yaml content this operator saw +
|
|
11964
|
+
* consented to (ADR-021). Trust-gate state: when the live source-config
|
|
11965
|
+
* differs from this snapshot, sync halts with a consent prompt instead
|
|
11966
|
+
* of silently rebranding. Snapshot is updated on accept; persists across
|
|
11967
|
+
* syncs. When undefined: operator has never seen a source-config from this
|
|
11968
|
+
* source (first-sync flow applies). Field shape mirrors SourceConfigSchema
|
|
11969
|
+
* for round-trip simplicity.
|
|
11970
|
+
*/
|
|
11971
|
+
lastSeenSourcePrefix: SourceConfigSnapshotSchema.optional()
|
|
11936
11972
|
});
|
|
11937
11973
|
}
|
|
11938
11974
|
});
|
|
@@ -12461,7 +12497,9 @@ var init_trust_audit_log = __esm({
|
|
|
12461
12497
|
"meta-hook-stripped",
|
|
12462
12498
|
"setup-skill-source-picked",
|
|
12463
12499
|
"setup-project-sweep-completed",
|
|
12464
|
-
"prefix-collision"
|
|
12500
|
+
"prefix-collision",
|
|
12501
|
+
"source-prefix-adopted",
|
|
12502
|
+
"source-prefix-changed"
|
|
12465
12503
|
]);
|
|
12466
12504
|
TrustMethodSchema = external_exports.enum(["flag", "interactive", "auto-reject-tty", "none"]);
|
|
12467
12505
|
TrustAuditEntrySchema = external_exports.object({
|
|
@@ -12575,7 +12613,7 @@ function updateSkillSource(id, patch) {
|
|
|
12575
12613
|
}
|
|
12576
12614
|
}
|
|
12577
12615
|
if (patch.prefix !== void 0 && patch.prefix !== null) {
|
|
12578
|
-
if (!
|
|
12616
|
+
if (!PREFIX_PATTERN3.test(patch.prefix)) {
|
|
12579
12617
|
throw new Error(`prefix must match /^[a-z0-9][a-z0-9_-]{0,38}$/ \u2014 got "${patch.prefix}"`);
|
|
12580
12618
|
}
|
|
12581
12619
|
}
|
|
@@ -12595,6 +12633,14 @@ function updateSkillSource(id, patch) {
|
|
|
12595
12633
|
} else if (patch.prefixScope !== void 0) {
|
|
12596
12634
|
working = { ...working, prefixScope: [...patch.prefixScope] };
|
|
12597
12635
|
}
|
|
12636
|
+
if (patch.lastSeenSourcePrefix === null) {
|
|
12637
|
+
const { lastSeenSourcePrefix: _l, ...rest } = working;
|
|
12638
|
+
void _l;
|
|
12639
|
+
working = rest;
|
|
12640
|
+
} else if (patch.lastSeenSourcePrefix !== void 0) {
|
|
12641
|
+
const validated = SourceConfigSnapshotSchema.parse(patch.lastSeenSourcePrefix);
|
|
12642
|
+
working = { ...working, lastSeenSourcePrefix: validated };
|
|
12643
|
+
}
|
|
12598
12644
|
const updated = {
|
|
12599
12645
|
...working,
|
|
12600
12646
|
...patch.name !== void 0 ? { name: patch.name } : {},
|
|
@@ -12606,14 +12652,15 @@ function updateSkillSource(id, patch) {
|
|
|
12606
12652
|
writeGlobalConfig({ ...config2, skillSources: next });
|
|
12607
12653
|
return updated;
|
|
12608
12654
|
}
|
|
12609
|
-
var
|
|
12655
|
+
var PREFIX_PATTERN3;
|
|
12610
12656
|
var init_store2 = __esm({
|
|
12611
12657
|
"../core/dist/skill-sources/store.js"() {
|
|
12612
12658
|
"use strict";
|
|
12613
12659
|
init_store();
|
|
12614
12660
|
init_schema3();
|
|
12615
12661
|
init_trust_audit_log();
|
|
12616
|
-
|
|
12662
|
+
init_source_config_schema();
|
|
12663
|
+
PREFIX_PATTERN3 = /^[a-z0-9][a-z0-9_-]{0,38}$/;
|
|
12617
12664
|
}
|
|
12618
12665
|
});
|
|
12619
12666
|
|
|
@@ -15060,6 +15107,97 @@ var init_prefix_deploy = __esm({
|
|
|
15060
15107
|
}
|
|
15061
15108
|
});
|
|
15062
15109
|
|
|
15110
|
+
// ../core/dist/skill-sync/resolve-source-config.js
|
|
15111
|
+
import { readFileSync as readFileSync29, existsSync as existsSync31 } from "node:fs";
|
|
15112
|
+
import { join as join31 } from "node:path";
|
|
15113
|
+
import { parse as parseYaml4 } from "yaml";
|
|
15114
|
+
function sourceConfigPath(clonePath) {
|
|
15115
|
+
return join31(clonePath, "shared", "source-config.yaml");
|
|
15116
|
+
}
|
|
15117
|
+
function readSourceConfig(clonePath, sourceId) {
|
|
15118
|
+
const path52 = sourceConfigPath(clonePath);
|
|
15119
|
+
if (!existsSync31(path52))
|
|
15120
|
+
return void 0;
|
|
15121
|
+
let raw;
|
|
15122
|
+
try {
|
|
15123
|
+
raw = readFileSync29(path52, "utf-8");
|
|
15124
|
+
} catch (err) {
|
|
15125
|
+
emitMalformedWarning(sourceId, `read failed: ${errToMsg(err)}`);
|
|
15126
|
+
return void 0;
|
|
15127
|
+
}
|
|
15128
|
+
let parsed;
|
|
15129
|
+
try {
|
|
15130
|
+
parsed = parseYaml4(raw);
|
|
15131
|
+
} catch (err) {
|
|
15132
|
+
emitMalformedWarning(sourceId, `YAML parse failed: ${errToMsg(err)}`);
|
|
15133
|
+
return void 0;
|
|
15134
|
+
}
|
|
15135
|
+
const candidate = parsed === null || parsed === void 0 ? {} : parsed;
|
|
15136
|
+
const result = SourceConfigSchema.safeParse(candidate);
|
|
15137
|
+
if (!result.success) {
|
|
15138
|
+
emitMalformedWarning(sourceId, `schema validation failed: ${result.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ")}`);
|
|
15139
|
+
return void 0;
|
|
15140
|
+
}
|
|
15141
|
+
return result.data;
|
|
15142
|
+
}
|
|
15143
|
+
function emitMalformedWarning(sourceId, reason) {
|
|
15144
|
+
const id = sourceId ?? "<unknown source>";
|
|
15145
|
+
process.stderr.write(`[source-config:malformed] ${id}: ${reason}
|
|
15146
|
+
`);
|
|
15147
|
+
}
|
|
15148
|
+
function errToMsg(err) {
|
|
15149
|
+
return err instanceof Error ? err.message : String(err);
|
|
15150
|
+
}
|
|
15151
|
+
function resolveEffectivePrefix(operatorSource, sourceConfig) {
|
|
15152
|
+
const opPrefix = operatorSource.prefix;
|
|
15153
|
+
const opScope = operatorSource.prefixScope;
|
|
15154
|
+
const srcPrefix = sourceConfig?.prefix;
|
|
15155
|
+
const srcScope = sourceConfig?.prefixScope;
|
|
15156
|
+
const effectivePrefix = opPrefix ?? srcPrefix;
|
|
15157
|
+
const effectiveScope = opScope ?? srcScope;
|
|
15158
|
+
const operatorHasAny = opPrefix !== void 0 || opScope !== void 0 && opScope.length > 0;
|
|
15159
|
+
const sourceHasAny = srcPrefix !== void 0 || srcScope !== void 0 && srcScope.length > 0;
|
|
15160
|
+
const origin = operatorHasAny ? "operator" : sourceHasAny ? "source" : "none";
|
|
15161
|
+
const result = { origin };
|
|
15162
|
+
if (effectivePrefix !== void 0)
|
|
15163
|
+
result.prefix = effectivePrefix;
|
|
15164
|
+
if (effectiveScope !== void 0)
|
|
15165
|
+
result.prefixScope = effectiveScope;
|
|
15166
|
+
return result;
|
|
15167
|
+
}
|
|
15168
|
+
function sourceConfigsEqual(a, b) {
|
|
15169
|
+
const normalize = (c) => {
|
|
15170
|
+
if (c === void 0)
|
|
15171
|
+
return {};
|
|
15172
|
+
const out = {};
|
|
15173
|
+
if (c.prefix !== void 0)
|
|
15174
|
+
out.prefix = c.prefix;
|
|
15175
|
+
if (c.prefixScope !== void 0 && c.prefixScope.length > 0) {
|
|
15176
|
+
out.prefixScope = [...c.prefixScope];
|
|
15177
|
+
}
|
|
15178
|
+
return out;
|
|
15179
|
+
};
|
|
15180
|
+
const na = normalize(a);
|
|
15181
|
+
const nb = normalize(b);
|
|
15182
|
+
if (na.prefix !== nb.prefix)
|
|
15183
|
+
return false;
|
|
15184
|
+
const sa = na.prefixScope ?? [];
|
|
15185
|
+
const sb = nb.prefixScope ?? [];
|
|
15186
|
+
if (sa.length !== sb.length)
|
|
15187
|
+
return false;
|
|
15188
|
+
for (let i = 0; i < sa.length; i++) {
|
|
15189
|
+
if (sa[i] !== sb[i])
|
|
15190
|
+
return false;
|
|
15191
|
+
}
|
|
15192
|
+
return true;
|
|
15193
|
+
}
|
|
15194
|
+
var init_resolve_source_config = __esm({
|
|
15195
|
+
"../core/dist/skill-sync/resolve-source-config.js"() {
|
|
15196
|
+
"use strict";
|
|
15197
|
+
init_source_config_schema();
|
|
15198
|
+
}
|
|
15199
|
+
});
|
|
15200
|
+
|
|
15063
15201
|
// ../core/dist/skill-sync/engine.js
|
|
15064
15202
|
import * as fs31 from "node:fs";
|
|
15065
15203
|
import * as os18 from "node:os";
|
|
@@ -15120,8 +15258,95 @@ async function syncSkills(opts = {}) {
|
|
|
15120
15258
|
const memberOverlaysEnabled = process.env["OLAM_MEMBER_OVERLAYS"] === "1";
|
|
15121
15259
|
const baseArtifacts = projectFilteredArtifacts.filter((a) => a.kind !== "overlay");
|
|
15122
15260
|
const overlayArtifacts = memberOverlaysEnabled ? projectFilteredArtifacts.filter((a) => a.kind === "overlay") : [];
|
|
15123
|
-
const
|
|
15124
|
-
|
|
15261
|
+
const effectiveSources = sources.map((s) => {
|
|
15262
|
+
const clonePath = skillSourceClonePath(s.id);
|
|
15263
|
+
const sourceConfig = fs31.existsSync(clonePath) ? readSourceConfig(clonePath, s.id) : void 0;
|
|
15264
|
+
const eff = resolveEffectivePrefix(s, sourceConfig);
|
|
15265
|
+
const entry = {
|
|
15266
|
+
id: s.id,
|
|
15267
|
+
origin: eff.origin,
|
|
15268
|
+
sourceConfig
|
|
15269
|
+
};
|
|
15270
|
+
if (eff.prefix !== void 0)
|
|
15271
|
+
entry.prefix = eff.prefix;
|
|
15272
|
+
if (eff.prefixScope !== void 0)
|
|
15273
|
+
entry.prefixScope = eff.prefixScope;
|
|
15274
|
+
return entry;
|
|
15275
|
+
});
|
|
15276
|
+
const sourcePrefixGateOutcomes = [];
|
|
15277
|
+
for (const eff of effectiveSources) {
|
|
15278
|
+
if (eff.sourceConfig === void 0) {
|
|
15279
|
+
sourcePrefixGateOutcomes.push({ sourceId: eff.id, outcome: "no-source-config" });
|
|
15280
|
+
continue;
|
|
15281
|
+
}
|
|
15282
|
+
if (eff.origin === "operator") {
|
|
15283
|
+
sourcePrefixGateOutcomes.push({ sourceId: eff.id, outcome: "no-change" });
|
|
15284
|
+
continue;
|
|
15285
|
+
}
|
|
15286
|
+
const operatorSource = sources.find((s) => s.id === eff.id);
|
|
15287
|
+
const lastSeen = operatorSource?.lastSeenSourcePrefix;
|
|
15288
|
+
const sameAsLastSeen = sourceConfigsEqual(lastSeen, eff.sourceConfig);
|
|
15289
|
+
if (sameAsLastSeen) {
|
|
15290
|
+
sourcePrefixGateOutcomes.push({ sourceId: eff.id, outcome: "no-change" });
|
|
15291
|
+
continue;
|
|
15292
|
+
}
|
|
15293
|
+
const kind = lastSeen === void 0 ? "first-time" : "changed";
|
|
15294
|
+
const flagGrant = kind === "first-time" && opts.autoAcceptSourcePrefix === true || kind === "changed" && opts.acceptSourcePrefixChanges === true;
|
|
15295
|
+
let consented = flagGrant;
|
|
15296
|
+
if (!consented && opts.sourcePrefixPrompt !== void 0) {
|
|
15297
|
+
try {
|
|
15298
|
+
const promptInput = {
|
|
15299
|
+
sourceName: operatorSource?.name ?? eff.id,
|
|
15300
|
+
sourceId: eff.id,
|
|
15301
|
+
newConfig: eff.sourceConfig,
|
|
15302
|
+
kind
|
|
15303
|
+
};
|
|
15304
|
+
if (lastSeen !== void 0)
|
|
15305
|
+
promptInput.priorConfig = lastSeen;
|
|
15306
|
+
consented = await opts.sourcePrefixPrompt(promptInput);
|
|
15307
|
+
} catch {
|
|
15308
|
+
consented = false;
|
|
15309
|
+
}
|
|
15310
|
+
}
|
|
15311
|
+
if (consented) {
|
|
15312
|
+
if (!opts.dryRun) {
|
|
15313
|
+
try {
|
|
15314
|
+
updateSkillSource(eff.id, { lastSeenSourcePrefix: eff.sourceConfig });
|
|
15315
|
+
appendTrustAudit({
|
|
15316
|
+
gitUrl: `internal:source-prefix-${kind === "first-time" ? "adopted" : "changed"}`,
|
|
15317
|
+
action: kind === "first-time" ? "source-prefix-adopted" : "source-prefix-changed",
|
|
15318
|
+
trustMethod: flagGrant ? "flag" : "interactive",
|
|
15319
|
+
sourceId: eff.id,
|
|
15320
|
+
note: kind === "first-time" ? `snapshot=${JSON.stringify(eff.sourceConfig)}` : `prior=${JSON.stringify(lastSeen ?? {})}; new=${JSON.stringify(eff.sourceConfig)}`
|
|
15321
|
+
});
|
|
15322
|
+
} catch {
|
|
15323
|
+
}
|
|
15324
|
+
}
|
|
15325
|
+
sourcePrefixGateOutcomes.push({
|
|
15326
|
+
sourceId: eff.id,
|
|
15327
|
+
outcome: kind === "first-time" ? "adopted" : "changed"
|
|
15328
|
+
});
|
|
15329
|
+
} else {
|
|
15330
|
+
delete eff.prefix;
|
|
15331
|
+
delete eff.prefixScope;
|
|
15332
|
+
eff.origin = "none";
|
|
15333
|
+
const isNonTty = opts.sourcePrefixPrompt === void 0;
|
|
15334
|
+
sourcePrefixGateOutcomes.push({
|
|
15335
|
+
sourceId: eff.id,
|
|
15336
|
+
outcome: isNonTty ? "skipped-non-tty" : "rejected"
|
|
15337
|
+
});
|
|
15338
|
+
if (isNonTty) {
|
|
15339
|
+
process.stderr.write(`[source-prefix:skipped] ${operatorSource?.name ?? eff.id}: source-config has prefix-suggestion '${eff.sourceConfig.prefix ?? "<empty>"}' but no consent (non-TTY without --auto-accept-source-prefix). Skipping for this sync; canonical names deployed.
|
|
15340
|
+
`);
|
|
15341
|
+
}
|
|
15342
|
+
}
|
|
15343
|
+
}
|
|
15344
|
+
const sourcePrefixMap = buildSourcePrefixMap(effectiveSources);
|
|
15345
|
+
const hasPrefixRewrites = effectiveSources.some((s) => s.prefix !== void 0 && s.prefix.length > 0);
|
|
15346
|
+
const effectivePrefixOrigins = {};
|
|
15347
|
+
for (const s of effectiveSources) {
|
|
15348
|
+
effectivePrefixOrigins[s.id] = s.origin;
|
|
15349
|
+
}
|
|
15125
15350
|
const willMutateManagedDir = !opts.dryRun && (memberOverlaysEnabled && overlayArtifacts.length > 0 || hasPrefixRewrites);
|
|
15126
15351
|
if (willMutateManagedDir) {
|
|
15127
15352
|
const claude = claudeDir();
|
|
@@ -15170,7 +15395,7 @@ async function syncSkills(opts = {}) {
|
|
|
15170
15395
|
const permissionFiles = projectFilteredArtifacts.filter((a) => a.kind === "permission").map((a) => a.sourcePath);
|
|
15171
15396
|
const claudeDirForRewrites = claudeDir();
|
|
15172
15397
|
const prefixRewriteResult = applyPrefixRewrites(baseArtifacts, sourcePrefixMap, claudeDirForRewrites, opts.dryRun === true);
|
|
15173
|
-
const prefixCollisions = detectPrefixCollisions(
|
|
15398
|
+
const prefixCollisions = detectPrefixCollisions(effectiveSources);
|
|
15174
15399
|
if (!opts.dryRun) {
|
|
15175
15400
|
for (const collision of prefixCollisions) {
|
|
15176
15401
|
try {
|
|
@@ -15197,7 +15422,9 @@ async function syncSkills(opts = {}) {
|
|
|
15197
15422
|
metaHooks: void 0,
|
|
15198
15423
|
perSource,
|
|
15199
15424
|
prefixRewrites: prefixRewriteResult.entries,
|
|
15200
|
-
prefixCollisions
|
|
15425
|
+
prefixCollisions,
|
|
15426
|
+
effectivePrefixOrigins,
|
|
15427
|
+
sourcePrefixGateOutcomes
|
|
15201
15428
|
};
|
|
15202
15429
|
if (opts.dryRun) {
|
|
15203
15430
|
summary.collisions = detectCollisions(baseArtifacts).collisions;
|
|
@@ -15329,6 +15556,8 @@ var init_engine = __esm({
|
|
|
15329
15556
|
init_markdown_merger();
|
|
15330
15557
|
init_managed_merge();
|
|
15331
15558
|
init_prefix_deploy();
|
|
15559
|
+
init_resolve_source_config();
|
|
15560
|
+
init_store2();
|
|
15332
15561
|
}
|
|
15333
15562
|
});
|
|
15334
15563
|
|
|
@@ -15841,6 +16070,8 @@ __export(skill_sources_exports, {
|
|
|
15841
16070
|
SkillOverrideSchema: () => SkillOverrideSchema,
|
|
15842
16071
|
SkillSourceGitError: () => SkillSourceGitError,
|
|
15843
16072
|
SkillSourceSchema: () => SkillSourceSchema,
|
|
16073
|
+
SourceConfigSchema: () => SourceConfigSchema,
|
|
16074
|
+
SourceConfigSnapshotSchema: () => SourceConfigSnapshotSchema,
|
|
15844
16075
|
TrustActionSchema: () => TrustActionSchema,
|
|
15845
16076
|
TrustAuditEntrySchema: () => TrustAuditEntrySchema,
|
|
15846
16077
|
TrustMethodSchema: () => TrustMethodSchema,
|
|
@@ -15880,12 +16111,14 @@ __export(skill_sources_exports, {
|
|
|
15880
16111
|
pullSkillSource: () => pullSkillSource,
|
|
15881
16112
|
readLatestMigrationSnapshot: () => readLatestMigrationSnapshot,
|
|
15882
16113
|
readMigrationSnapshotFromPath: () => readMigrationSnapshotFromPath,
|
|
16114
|
+
readSourceConfig: () => readSourceConfig,
|
|
15883
16115
|
readTrustAuditLog: () => readTrustAuditLog,
|
|
15884
16116
|
redactUrl: () => redactUrl2,
|
|
15885
16117
|
removeSkillSource: () => removeSkillSource,
|
|
15886
16118
|
removeSkillSourceClone: () => removeSkillSourceClone,
|
|
15887
16119
|
reorderSkillSource: () => reorderSkillSource,
|
|
15888
16120
|
resolveAtlasUser: () => resolveAtlasUser,
|
|
16121
|
+
resolveEffectivePrefix: () => resolveEffectivePrefix,
|
|
15889
16122
|
resolveSourceArtifacts: () => resolveSourceArtifacts,
|
|
15890
16123
|
resolveSubscriptions: () => resolveSubscriptions,
|
|
15891
16124
|
restoreCloneToBranchHead: () => restoreCloneToBranchHead,
|
|
@@ -15896,6 +16129,8 @@ __export(skill_sources_exports, {
|
|
|
15896
16129
|
skillSourcesAuditLogPath: () => skillSourcesAuditLogPath,
|
|
15897
16130
|
skillSourcesRootDir: () => skillSourcesRootDir,
|
|
15898
16131
|
skillsHookSettingsPathFor: () => settingsPathFor,
|
|
16132
|
+
sourceConfigPath: () => sourceConfigPath,
|
|
16133
|
+
sourceConfigsEqual: () => sourceConfigsEqual,
|
|
15899
16134
|
syncSkills: () => syncSkills,
|
|
15900
16135
|
uninstallSkillsHookFromFile: () => uninstallSkillsHookFromFile,
|
|
15901
16136
|
updateSkillSource: () => updateSkillSource,
|
|
@@ -15912,6 +16147,8 @@ var init_skill_sources = __esm({
|
|
|
15912
16147
|
init_hook_install();
|
|
15913
16148
|
init_migration_snapshot();
|
|
15914
16149
|
init_engine();
|
|
16150
|
+
init_resolve_source_config();
|
|
16151
|
+
init_source_config_schema();
|
|
15915
16152
|
init_file_lock();
|
|
15916
16153
|
init_schema5();
|
|
15917
16154
|
init_per_project_override();
|
|
@@ -36489,7 +36726,7 @@ import * as path41 from "node:path";
|
|
|
36489
36726
|
|
|
36490
36727
|
// ../core/dist/kg/storage-paths.js
|
|
36491
36728
|
import { homedir as homedir24 } from "node:os";
|
|
36492
|
-
import { join as
|
|
36729
|
+
import { join as join41, resolve as resolve9 } from "node:path";
|
|
36493
36730
|
|
|
36494
36731
|
// ../core/dist/world/workspace-name.js
|
|
36495
36732
|
var InvalidWorkspaceNameError = class extends Error {
|
|
@@ -36510,13 +36747,13 @@ function validateWorkspaceName(name) {
|
|
|
36510
36747
|
|
|
36511
36748
|
// ../core/dist/kg/storage-paths.js
|
|
36512
36749
|
function olamHome() {
|
|
36513
|
-
return process.env.OLAM_HOME ??
|
|
36750
|
+
return process.env.OLAM_HOME ?? join41(homedir24(), ".olam");
|
|
36514
36751
|
}
|
|
36515
36752
|
function kgRoot() {
|
|
36516
|
-
return
|
|
36753
|
+
return join41(olamHome(), "kg");
|
|
36517
36754
|
}
|
|
36518
36755
|
function worldsRoot() {
|
|
36519
|
-
return
|
|
36756
|
+
return join41(olamHome(), "worlds");
|
|
36520
36757
|
}
|
|
36521
36758
|
function assertWithinPrefix(path52, prefix, label) {
|
|
36522
36759
|
if (!path52.startsWith(prefix + "/")) {
|
|
@@ -36526,7 +36763,7 @@ function assertWithinPrefix(path52, prefix, label) {
|
|
|
36526
36763
|
function kgPristinePath(workspace) {
|
|
36527
36764
|
validateWorkspaceName(workspace);
|
|
36528
36765
|
const root = kgRoot();
|
|
36529
|
-
const path52 = resolve9(
|
|
36766
|
+
const path52 = resolve9(join41(root, workspace));
|
|
36530
36767
|
assertWithinPrefix(path52, root, "kgPristinePath");
|
|
36531
36768
|
return path52;
|
|
36532
36769
|
}
|
|
@@ -36804,7 +37041,7 @@ function extractStderr(err) {
|
|
|
36804
37041
|
function carryUncommittedEdits(repos, workspacePath, deps = {}) {
|
|
36805
37042
|
const exec = deps.exec ?? ((cmd, args, opts) => execFileSync6(cmd, args, opts));
|
|
36806
37043
|
const homedir30 = deps.homedir ?? (() => os26.homedir());
|
|
36807
|
-
const
|
|
37044
|
+
const existsSync48 = deps.existsSync ?? ((p) => fs42.existsSync(p));
|
|
36808
37045
|
const copyFileSync9 = deps.copyFileSync ?? ((src, dest) => fs42.copyFileSync(src, dest));
|
|
36809
37046
|
const mkdirSync30 = deps.mkdirSync ?? ((dirPath, opts) => {
|
|
36810
37047
|
fs42.mkdirSync(dirPath, opts);
|
|
@@ -36815,9 +37052,9 @@ function carryUncommittedEdits(repos, workspacePath, deps = {}) {
|
|
|
36815
37052
|
continue;
|
|
36816
37053
|
const repoPath = expandHome2(repo.path, homedir30);
|
|
36817
37054
|
const worktreePath = path42.join(workspacePath, repo.name);
|
|
36818
|
-
if (!
|
|
37055
|
+
if (!existsSync48(repoPath))
|
|
36819
37056
|
continue;
|
|
36820
|
-
if (!
|
|
37057
|
+
if (!existsSync48(worktreePath)) {
|
|
36821
37058
|
console.warn(`[carry] ${repo.name}: world worktree ${worktreePath} missing; skipping carry for this repo`);
|
|
36822
37059
|
continue;
|
|
36823
37060
|
}
|
|
@@ -36877,7 +37114,7 @@ function carryUncommittedEdits(repos, workspacePath, deps = {}) {
|
|
|
36877
37114
|
for (const rel of plan.diff.untracked) {
|
|
36878
37115
|
const src = path42.join(plan.repoPath, rel);
|
|
36879
37116
|
const dest = path42.join(plan.worktreePath, rel);
|
|
36880
|
-
if (!
|
|
37117
|
+
if (!existsSync48(src))
|
|
36881
37118
|
continue;
|
|
36882
37119
|
try {
|
|
36883
37120
|
mkdirSync30(path42.dirname(dest), { recursive: true });
|
|
@@ -38139,14 +38376,14 @@ function enrichReposWithManifests(repos, workspacePath) {
|
|
|
38139
38376
|
// ../core/dist/policies/loader.js
|
|
38140
38377
|
import * as fs45 from "node:fs";
|
|
38141
38378
|
import * as path46 from "node:path";
|
|
38142
|
-
import { parse as
|
|
38379
|
+
import { parse as parseYaml5 } from "yaml";
|
|
38143
38380
|
function parseFrontmatter2(content) {
|
|
38144
38381
|
const match = /^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/m.exec(content);
|
|
38145
38382
|
if (!match)
|
|
38146
38383
|
return null;
|
|
38147
38384
|
const [, yamlText = "", body = ""] = match;
|
|
38148
38385
|
try {
|
|
38149
|
-
const frontmatter =
|
|
38386
|
+
const frontmatter = parseYaml5(yamlText);
|
|
38150
38387
|
return { frontmatter, body };
|
|
38151
38388
|
} catch {
|
|
38152
38389
|
return null;
|
|
@@ -41447,8 +41684,8 @@ var PleriClient = class {
|
|
|
41447
41684
|
};
|
|
41448
41685
|
|
|
41449
41686
|
// ../mcp-server/src/env-loader.ts
|
|
41450
|
-
import { readFileSync as
|
|
41451
|
-
import { join as
|
|
41687
|
+
import { readFileSync as readFileSync39, existsSync as existsSync47, statSync as statSync14 } from "node:fs";
|
|
41688
|
+
import { join as join52, dirname as dirname29, resolve as resolve13 } from "node:path";
|
|
41452
41689
|
var PROJECT_MARKERS = [
|
|
41453
41690
|
".olam/config.yaml",
|
|
41454
41691
|
".olam/config.yml",
|
|
@@ -41460,12 +41697,12 @@ function findProjectRoot2(startDir) {
|
|
|
41460
41697
|
const root = resolve13("/");
|
|
41461
41698
|
while (true) {
|
|
41462
41699
|
for (const marker of PROJECT_MARKERS) {
|
|
41463
|
-
if (
|
|
41700
|
+
if (existsSync47(join52(dir, marker))) return dir;
|
|
41464
41701
|
}
|
|
41465
|
-
const pkg =
|
|
41466
|
-
if (
|
|
41702
|
+
const pkg = join52(dir, "package.json");
|
|
41703
|
+
if (existsSync47(pkg)) {
|
|
41467
41704
|
try {
|
|
41468
|
-
const json = JSON.parse(
|
|
41705
|
+
const json = JSON.parse(readFileSync39(pkg, "utf8"));
|
|
41469
41706
|
const isOlamWorkspace = typeof json.name === "string" && json.name.startsWith("@olam/");
|
|
41470
41707
|
const hasOlamDep = json.dependencies && Object.keys(json.dependencies).some((k) => k.startsWith("@olam/")) || json.devDependencies && Object.keys(json.devDependencies).some((k) => k.startsWith("@olam/"));
|
|
41471
41708
|
if (isOlamWorkspace || hasOlamDep) return dir;
|
|
@@ -41479,7 +41716,7 @@ function findProjectRoot2(startDir) {
|
|
|
41479
41716
|
}
|
|
41480
41717
|
function parseEnvFile(path52) {
|
|
41481
41718
|
const out = {};
|
|
41482
|
-
const raw =
|
|
41719
|
+
const raw = readFileSync39(path52, "utf8");
|
|
41483
41720
|
for (const line of raw.split(/\r?\n/)) {
|
|
41484
41721
|
const trimmed = line.trim();
|
|
41485
41722
|
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
@@ -41502,8 +41739,8 @@ function loadProjectEnv(startDir = process.cwd()) {
|
|
|
41502
41739
|
const filesRead = [];
|
|
41503
41740
|
const merged = {};
|
|
41504
41741
|
for (const name of [".env", ".env.local"]) {
|
|
41505
|
-
const p =
|
|
41506
|
-
if (
|
|
41742
|
+
const p = join52(root, name);
|
|
41743
|
+
if (existsSync47(p) && statSync14(p).isFile()) {
|
|
41507
41744
|
Object.assign(merged, parseEnvFile(p));
|
|
41508
41745
|
filesRead.push(p);
|
|
41509
41746
|
}
|
|
@@ -111,7 +111,7 @@ spec:
|
|
|
111
111
|
# k3d), started by `olam upgrade` Step 0.7 — not inside this Pod.
|
|
112
112
|
containers:
|
|
113
113
|
- name: olam-host-cp
|
|
114
|
-
image: ghcr.io/pleri/olam-host-cp@sha256:
|
|
114
|
+
image: ghcr.io/pleri/olam-host-cp@sha256:766e07263fcf7e765c3689a7b8d40c47754b4ab90c697710843265a7fc84969a
|
|
115
115
|
imagePullPolicy: IfNotPresent
|
|
116
116
|
securityContext:
|
|
117
117
|
runAsNonRoot: true
|
|
@@ -70,7 +70,7 @@ spec:
|
|
|
70
70
|
mountPath: /data
|
|
71
71
|
containers:
|
|
72
72
|
- name: olam-auth-service
|
|
73
|
-
image: ghcr.io/pleri/olam-auth@sha256:
|
|
73
|
+
image: ghcr.io/pleri/olam-auth@sha256:c6d163f7ac5fe1ca4652ed34afb1d8555c6f61d06398db767db65fee0944b209
|
|
74
74
|
imagePullPolicy: IfNotPresent
|
|
75
75
|
securityContext:
|
|
76
76
|
runAsNonRoot: true
|
|
@@ -61,7 +61,7 @@ spec:
|
|
|
61
61
|
mountPath: /data
|
|
62
62
|
containers:
|
|
63
63
|
- name: olam-kg-service
|
|
64
|
-
image: ghcr.io/pleri/olam-kg-service@sha256:
|
|
64
|
+
image: ghcr.io/pleri/olam-kg-service@sha256:77fd9b19d87c6f4cba4d33d76ff476dd7677f78725f3bf75a9076009e17355cc
|
|
65
65
|
imagePullPolicy: IfNotPresent
|
|
66
66
|
securityContext:
|
|
67
67
|
runAsNonRoot: true
|
|
@@ -68,7 +68,7 @@ spec:
|
|
|
68
68
|
mountPath: /data
|
|
69
69
|
containers:
|
|
70
70
|
- name: olam-mcp-auth-service
|
|
71
|
-
image: ghcr.io/pleri/olam-mcp-auth@sha256:
|
|
71
|
+
image: ghcr.io/pleri/olam-mcp-auth@sha256:cb5b1d7caece5bca4a4723eb20522a748cd48001aa94a7e7ec106d29bd2142b0
|
|
72
72
|
imagePullPolicy: IfNotPresent
|
|
73
73
|
securityContext:
|
|
74
74
|
runAsNonRoot: true
|
|
@@ -70,7 +70,7 @@ spec:
|
|
|
70
70
|
# bootstrap-placeholder comment + run `npm run refresh:manifest-digests`
|
|
71
71
|
# once ghcr.io/pleri/olam-memory-service has a real published digest.
|
|
72
72
|
# bootstrap-placeholder: pre-publish; refresh after first release
|
|
73
|
-
image: ghcr.io/pleri/olam-memory-service@sha256:
|
|
73
|
+
image: ghcr.io/pleri/olam-memory-service@sha256:38b2c1f36e49183f5d36999c6519533a8402f3e784109ede8ad7f6e1a205c195
|
|
74
74
|
imagePullPolicy: IfNotPresent
|
|
75
75
|
securityContext:
|
|
76
76
|
runAsNonRoot: true
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// W4 — Halt-shape detection for the host-cp chunk-write proxy.
|
|
2
|
+
//
|
|
3
|
+
// When plan-DO's dispatchPlanningAgent (W1) trips a guardrail, it
|
|
4
|
+
// emits a chunk with chunk_type='goal_mode_assumption' and content
|
|
5
|
+
// matching: `[assumption: <cap>-tripped — spent $X.XXXX of $Y]` (or
|
|
6
|
+
// similar shape per GuardrailState.haltChunkText()).
|
|
7
|
+
//
|
|
8
|
+
// host-cp's /api/plan-chat proxy passes the chunk through to the
|
|
9
|
+
// chunks substrate AND, if it detects a halt-shaped chunk, broadcasts
|
|
10
|
+
// a typed `plan.halted` event on host-stream so the SPA's
|
|
11
|
+
// PlanHaltBanner subscriber fires.
|
|
12
|
+
//
|
|
13
|
+
// Extracted as a pure fn so it can be unit-tested without booting
|
|
14
|
+
// the host-cp server.
|
|
15
|
+
|
|
16
|
+
const HALT_RE =
|
|
17
|
+
/^\[assumption:\s*(usd|turns|tool_calls|wall_clock)-tripped(?:\s*—\s*spent\s*\$([0-9.]+))?/;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Detect a halt-shaped chunk + extract its components.
|
|
21
|
+
*
|
|
22
|
+
* Returns null when:
|
|
23
|
+
* - chunk is null/undefined
|
|
24
|
+
* - chunk_type isn't 'goal_mode_assumption'
|
|
25
|
+
* - content doesn't match the halt regex
|
|
26
|
+
*
|
|
27
|
+
* Returns the parsed payload otherwise. Caller broadcasts this as
|
|
28
|
+
* the `plan.halted` event payload.
|
|
29
|
+
*/
|
|
30
|
+
export function detectHaltChunk(chunk) {
|
|
31
|
+
if (!chunk || typeof chunk !== 'object') return null;
|
|
32
|
+
if (chunk.chunk_type !== 'goal_mode_assumption') return null;
|
|
33
|
+
if (typeof chunk.chunk !== 'string') return null;
|
|
34
|
+
const m = chunk.chunk.match(HALT_RE);
|
|
35
|
+
if (!m) return null;
|
|
36
|
+
return {
|
|
37
|
+
plan_id: chunk.session_id ?? 'unknown',
|
|
38
|
+
operator_id: chunk.operator_id ?? 'unknown',
|
|
39
|
+
halt_reason: m[1],
|
|
40
|
+
usd_spent_so_far: m[2] ? Number.parseFloat(m[2]) : undefined,
|
|
41
|
+
halted_at: Date.now(),
|
|
42
|
+
};
|
|
43
|
+
}
|