omp-fabric 1.0.4 → 1.1.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.
@@ -33,7 +33,7 @@ import {
33
33
  repairFabricGuestCode,
34
34
  resolveFabricIdentity,
35
35
  runFabricHandoffAtBoundary
36
- } from "./chunks/chunk-DOKANNFC.js";
36
+ } from "./chunks/chunk-TLSJXU4F.js";
37
37
  import "./chunks/chunk-7VIQNUPS.js";
38
38
  import {
39
39
  AgentTranscriptReader,
@@ -94,7 +94,7 @@ import {
94
94
  resolveAgentCwd,
95
95
  resolveOmpBinary,
96
96
  validateAgentCwdRequest
97
- } from "./chunks/chunk-FFWALVBN.js";
97
+ } from "./chunks/chunk-WXZP5VWP.js";
98
98
  import "./chunks/chunk-VPPIJRNZ.js";
99
99
  import {
100
100
  executeFile,
@@ -114,7 +114,7 @@ import {
114
114
  resolveAgentDir,
115
115
  resolveAvailableOmpModel,
116
116
  resolveFabricModel
117
- } from "./chunks/chunk-IFNDRFW7.js";
117
+ } from "./chunks/chunk-EZPERYEG.js";
118
118
  import {
119
119
  FABRIC_ACTOR_HOST_EVENTS,
120
120
  isFabricActorHostEvent,
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,YAAY,EAGb,MAAM,2BAA2B,CAAC;AA4JnC,wBAA8B,SAAS,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA4sBxE;AAED,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,YAAY,EAEb,MAAM,2BAA2B,CAAC;AAiKnC,wBAA8B,SAAS,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAqtBxE;AAED,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC"}
package/dist/index.js CHANGED
@@ -60,14 +60,14 @@ import {
60
60
  expandSkillDirMarkersForRead,
61
61
  expandSkillDirMarkersInSkillBlock,
62
62
  filterPrewalkContinuationMessages,
63
- formatSkillsForPrompt,
63
+ formatSkillsSection,
64
64
  hasPrewalkArmedPrompt,
65
65
  prewalkArmedPrompt,
66
66
  repairFabricGuestCode,
67
67
  resolveFabricIdentity,
68
68
  settleInPlacePrewalk,
69
69
  streamedToolCallName
70
- } from "./chunks/chunk-DOKANNFC.js";
70
+ } from "./chunks/chunk-TLSJXU4F.js";
71
71
  import "./chunks/chunk-7VIQNUPS.js";
72
72
  import {
73
73
  AgentTranscriptReader
@@ -196,7 +196,7 @@ import {
196
196
  loadFabricConfigForScope,
197
197
  resolveAgentDir,
198
198
  saveFabricConfig
199
- } from "./chunks/chunk-IFNDRFW7.js";
199
+ } from "./chunks/chunk-EZPERYEG.js";
200
200
  import {
201
201
  FABRIC_ACTOR_OMP_HOST_EVENTS
202
202
  } from "./chunks/chunk-UOSJZXJV.js";
@@ -213,7 +213,9 @@ import {
213
213
  resolveFabricModelGuidance
214
214
  } from "./chunks/chunk-77FQHHZD.js";
215
215
  import "./chunks/chunk-7363CD5A.js";
216
- import "./chunks/chunk-KAD7UWT2.js";
216
+ import {
217
+ writeJsonAtomic
218
+ } from "./chunks/chunk-KAD7UWT2.js";
217
219
  import {
218
220
  compactAtConfiguredThreshold,
219
221
  fabricExecTitleHintCached,
@@ -2175,23 +2177,35 @@ var fabricSchemaGuidance = (mode) => {
2175
2177
  };
2176
2178
 
2177
2179
  // src/core/skill-prompt.ts
2180
+ import { getActiveSkills, Settings } from "@oh-my-pi/pi-coding-agent";
2178
2181
  var OMP_SKILL_SECTION_MARKER = "<skills>";
2182
+ var OMP_SKILL_SECTION_HEADING = "# Skills & Rules\n";
2179
2183
  var OMP_SKILL_LOAD_INSTRUCTION = "Matching skill \u2192 MUST read `skill://<name>` first.";
2184
+ var OMP_CUSTOM_SKILL_LOAD_INSTRUCTION = "If a skill applies, you MUST read `skill://<name>` before proceeding.";
2180
2185
  var FABRIC_OMP_SKILL_LOAD_INSTRUCTION = "Matching skill \u2192 MUST read `skill://<name>` through `omp.read` inside `fabric_exec` first.";
2181
- var LEGACY_SKILL_LOAD_INSTRUCTION = "Use the read tool to load a skill's file when the task matches its description.";
2182
- var FABRIC_SKILL_LOAD_INSTRUCTION = "Use `omp.read` inside `fabric_exec` to load a skill's file when the task matches its description.";
2186
+ var FABRIC_CUSTOM_SKILL_LOAD_INSTRUCTION = "If a skill applies, you MUST read `skill://<name>` through `omp.read` inside `fabric_exec` before proceeding.";
2187
+ var activeSkills = () => getActiveSkills();
2188
+ var listableSkills = (skills) => {
2189
+ try {
2190
+ if (Settings.instance.get("skillful") === false) return [];
2191
+ } catch {
2192
+ return skills;
2193
+ }
2194
+ return skills;
2195
+ };
2183
2196
  var restoreSkillsForFullCodePrompt = (systemPrompt, skills) => {
2184
2197
  if (systemPrompt.includes(OMP_SKILL_SECTION_MARKER)) {
2185
- return systemPrompt.replace(
2186
- OMP_SKILL_LOAD_INSTRUCTION,
2187
- FABRIC_OMP_SKILL_LOAD_INSTRUCTION
2188
- );
2198
+ return systemPrompt.replace(OMP_SKILL_LOAD_INSTRUCTION, FABRIC_OMP_SKILL_LOAD_INSTRUCTION).replace(OMP_CUSTOM_SKILL_LOAD_INSTRUCTION, FABRIC_CUSTOM_SKILL_LOAD_INSTRUCTION);
2189
2199
  }
2190
- const section = formatSkillsForPrompt([...skills]).replace(
2191
- LEGACY_SKILL_LOAD_INSTRUCTION,
2192
- FABRIC_SKILL_LOAD_INSTRUCTION
2193
- );
2194
- return section ? `${systemPrompt}${section}` : systemPrompt;
2200
+ const section = formatSkillsSection(skills, FABRIC_OMP_SKILL_LOAD_INSTRUCTION);
2201
+ if (!section) return systemPrompt;
2202
+ const heading = systemPrompt.indexOf(OMP_SKILL_SECTION_HEADING);
2203
+ if (heading < 0) return `${systemPrompt}
2204
+
2205
+ ${section}`;
2206
+ const insertAt = heading + OMP_SKILL_SECTION_HEADING.length;
2207
+ return `${systemPrompt.slice(0, insertAt)}${section}
2208
+ ${systemPrompt.slice(insertAt)}`;
2195
2209
  };
2196
2210
 
2197
2211
  // src/core/proxy-contract.ts
@@ -2346,7 +2360,7 @@ var buildSkillReferenceGuidance = (prompt, skills) => {
2346
2360
  const body = prompt.slice(openingEnd + 2, closingTag);
2347
2361
  const invocationLines = body.split("\n").filter((line) => INVOCATION_VERB.test(line) && !NEGATED_INVOCATION.test(line));
2348
2362
  const referenced = skills.filter(
2349
- (skill) => skill.name !== active.name && skill.disableModelInvocation !== true && invocationLines.some((line) => referencesSkill(line, skill.name))
2363
+ (skill) => skill.name !== active.name && skill.hide !== true && invocationLines.some((line) => referencesSkill(line, skill.name))
2350
2364
  );
2351
2365
  if (referenced.length === 0) return void 0;
2352
2366
  const mappings = referenced.map((skill) => `- /${skill.name} -> ${JSON.stringify(skill.filePath)}`).join("\n");
@@ -2389,8 +2403,8 @@ var formatFailureProgress = (trace) => {
2389
2403
  );
2390
2404
  if (completed.length === 0) return void 0;
2391
2405
  const summaries = completed.slice(0, MAX_COMPLETED_CALLS).map((operation) => {
2392
- const path10 = operation.args.path;
2393
- return typeof path10 === "string" ? `${operation.ref}(${compactPath(path10)})` : operation.ref;
2406
+ const path11 = operation.args.path;
2407
+ return typeof path11 === "string" ? `${operation.ref}(${compactPath(path11)})` : operation.ref;
2394
2408
  });
2395
2409
  const omitted = completed.length - summaries.length;
2396
2410
  return [
@@ -4095,8 +4109,138 @@ var ompHostCompatibilityWarning = (version = detectOmpHostVersion()) => {
4095
4109
  return `OMP Fabric requires OMP >= ${MINIMUM_OMP_HOST_VERSION}; detected ${version}. Upgrade OMP before relying on Fabric continuation behavior.`;
4096
4110
  };
4097
4111
 
4098
- // src/ui/controller.ts
4112
+ // src/update/check.ts
4113
+ import fs3 from "node:fs";
4099
4114
  import path8 from "node:path";
4115
+ import { fileURLToPath } from "node:url";
4116
+ var PACKAGE_NAME = "omp-fabric";
4117
+ var REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;
4118
+ var UPGRADE_COMMAND = `omp plugin install ${PACKAGE_NAME}`;
4119
+ var REQUEST_TIMEOUT_MS = 4e3;
4120
+ var UPDATE_STATUS_KEY = "fabric-update";
4121
+ var UPDATE_CHECK_TTL_MS = 24 * 60 * 60 * 1e3;
4122
+ var updateCheckCachePath = (agentDir) => path8.join(agentDir, "fabric", "update-check.json");
4123
+ var installedVersionFromManifest = () => {
4124
+ let directory = path8.dirname(fileURLToPath(import.meta.url));
4125
+ while (true) {
4126
+ try {
4127
+ const manifest = JSON.parse(
4128
+ fs3.readFileSync(path8.join(directory, "package.json"), "utf8")
4129
+ );
4130
+ if (manifest.name === PACKAGE_NAME && typeof manifest.version === "string") {
4131
+ return manifest.version;
4132
+ }
4133
+ } catch {
4134
+ }
4135
+ const parent = path8.dirname(directory);
4136
+ if (parent === directory) return void 0;
4137
+ directory = parent;
4138
+ }
4139
+ };
4140
+ var readCache = (cachePath) => {
4141
+ try {
4142
+ const parsed = JSON.parse(fs3.readFileSync(cachePath, "utf8"));
4143
+ if (typeof parsed.checkedAt !== "number" || !Number.isFinite(parsed.checkedAt)) return void 0;
4144
+ if (typeof parsed.latest !== "string" || parsed.latest.length === 0) return void 0;
4145
+ return {
4146
+ format: 1,
4147
+ checkedAt: parsed.checkedAt,
4148
+ latest: parsed.latest,
4149
+ ...typeof parsed.notified === "string" ? { notified: parsed.notified } : {}
4150
+ };
4151
+ } catch {
4152
+ return void 0;
4153
+ }
4154
+ };
4155
+ var writeCache = (cachePath, value) => {
4156
+ try {
4157
+ writeJsonAtomic(cachePath, value, { space: 2, newline: true });
4158
+ } catch {
4159
+ }
4160
+ };
4161
+ var fetchLatestVersion = async (fetchImpl, timeoutMs) => {
4162
+ const controller = new AbortController();
4163
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
4164
+ timer.unref?.();
4165
+ try {
4166
+ const response = await fetchImpl(REGISTRY_URL, {
4167
+ signal: controller.signal,
4168
+ headers: { accept: "application/json" }
4169
+ });
4170
+ if (!response.ok) return void 0;
4171
+ const payload = await response.json();
4172
+ const version = payload?.version;
4173
+ return typeof version === "string" && version.length > 0 ? version : void 0;
4174
+ } catch {
4175
+ return void 0;
4176
+ } finally {
4177
+ clearTimeout(timer);
4178
+ }
4179
+ };
4180
+ var checkFabricUpdate = async (options) => {
4181
+ try {
4182
+ const installed = options.installedVersion ?? installedVersionFromManifest();
4183
+ if (installed === void 0) return void 0;
4184
+ const now = options.now ?? Date.now();
4185
+ const cachePath = updateCheckCachePath(options.agentDir);
4186
+ const cached = readCache(cachePath);
4187
+ const age = cached === void 0 ? void 0 : now - cached.checkedAt;
4188
+ const fresh = cached !== void 0 && age !== void 0 && age >= 0 && age < UPDATE_CHECK_TTL_MS;
4189
+ let record;
4190
+ if (fresh && cached !== void 0) {
4191
+ record = cached;
4192
+ } else {
4193
+ const latest = await fetchLatestVersion(
4194
+ options.fetchImpl ?? globalThis.fetch,
4195
+ options.timeoutMs ?? REQUEST_TIMEOUT_MS
4196
+ );
4197
+ if (latest === void 0) return void 0;
4198
+ record = {
4199
+ format: 1,
4200
+ checkedAt: now,
4201
+ latest,
4202
+ ...cached?.notified === void 0 ? {} : { notified: cached.notified }
4203
+ };
4204
+ }
4205
+ const behind = compareVersions(record.latest, installed) === 1;
4206
+ const announce = behind && record.notified !== record.latest;
4207
+ if (!fresh || announce) {
4208
+ writeCache(cachePath, announce ? { ...record, notified: record.latest } : record);
4209
+ }
4210
+ if (!announce) return void 0;
4211
+ return {
4212
+ installed,
4213
+ latest: record.latest,
4214
+ message: `${PACKAGE_NAME} ${installed} \u2192 ${record.latest} \xB7 ${UPGRADE_COMMAND}`
4215
+ };
4216
+ } catch {
4217
+ return void 0;
4218
+ }
4219
+ };
4220
+ var scheduleFabricUpdateCheck = async (context, options) => {
4221
+ if (!options.enabled || !context.hasUI) return;
4222
+ let sessionId;
4223
+ try {
4224
+ sessionId = context.sessionManager.getSessionId();
4225
+ } catch {
4226
+ return;
4227
+ }
4228
+ if (resolveFabricIdentity(sessionId).identity.kind !== "main") return;
4229
+ const notice = await checkFabricUpdate({
4230
+ agentDir: options.agentDir,
4231
+ ...options.installedVersion === void 0 ? {} : { installedVersion: options.installedVersion },
4232
+ ...options.fetchImpl === void 0 ? {} : { fetchImpl: options.fetchImpl },
4233
+ ...options.now === void 0 ? {} : { now: options.now }
4234
+ });
4235
+ if (notice === void 0) return;
4236
+ try {
4237
+ context.ui.setStatus(UPDATE_STATUS_KEY, notice.message);
4238
+ } catch {
4239
+ }
4240
+ };
4241
+
4242
+ // src/ui/controller.ts
4243
+ import path9 from "node:path";
4100
4244
 
4101
4245
  // src/ui/snapshot.ts
4102
4246
  var MAX_UI_AGENTS = 240;
@@ -4953,7 +5097,7 @@ var FabricUiController = class {
4953
5097
  logFile: actor.worker.logFile
4954
5098
  };
4955
5099
  }
4956
- const retained = actor.lastRunId && actor.logDir ? path8.join(actor.logDir, actor.lastRunId, "events.jsonl") : void 0;
5100
+ const retained = actor.lastRunId && actor.logDir ? path9.join(actor.logDir, actor.lastRunId, "events.jsonl") : void 0;
4957
5101
  if (retained) return { id: actor.id, status: actor.status, logFile: retained };
4958
5102
  if (actor.sessionFile) {
4959
5103
  return { id: actor.id, status: actor.status, logFile: actor.sessionFile };
@@ -5112,15 +5256,15 @@ var REFRESH_CARDS_PER_TICK = 3;
5112
5256
 
5113
5257
  // src/index.ts
5114
5258
  import { existsSync as existsSync4 } from "node:fs";
5115
- import path9 from "node:path";
5116
- import { fileURLToPath } from "node:url";
5117
- var FABRIC_EXTENSION_ENTRY_PATH = path9.resolve(fileURLToPath(import.meta.url));
5118
- var FABRIC_ENTRY_DIR = path9.dirname(FABRIC_EXTENSION_ENTRY_PATH);
5259
+ import path10 from "node:path";
5260
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
5261
+ var FABRIC_EXTENSION_ENTRY_PATH = path10.resolve(fileURLToPath2(import.meta.url));
5262
+ var FABRIC_ENTRY_DIR = path10.dirname(FABRIC_EXTENSION_ENTRY_PATH);
5119
5263
  var FABRIC_RUNTIME_PATHS = {
5120
5264
  extension: FABRIC_EXTENSION_ENTRY_PATH,
5121
- worker: path9.join(FABRIC_ENTRY_DIR, "worker.js"),
5122
- residentHost: path9.join(FABRIC_ENTRY_DIR, "residency", "launcher.js"),
5123
- skills: path9.resolve(FABRIC_ENTRY_DIR, "..", "skills")
5265
+ worker: path10.join(FABRIC_ENTRY_DIR, "worker.js"),
5266
+ residentHost: path10.join(FABRIC_ENTRY_DIR, "residency", "launcher.js"),
5267
+ skills: path10.resolve(FABRIC_ENTRY_DIR, "..", "skills")
5124
5268
  };
5125
5269
  var FABRIC_SKILLS_DIR = FABRIC_RUNTIME_PATHS.skills;
5126
5270
  var componentRegistrationFrom = (value) => {
@@ -5146,6 +5290,7 @@ async function ompFabric(omp) {
5146
5290
  const codePreviewSettings = defaultCodePreviewSettings();
5147
5291
  const decorateShell = withCodePreviewShell;
5148
5292
  let compatibilityWarningShown = false;
5293
+ let updateCheckStarted = false;
5149
5294
  configureHighlighting(
5150
5295
  codePreviewSettings.shikiTheme,
5151
5296
  codePreviewSettings.syntaxHighlighting
@@ -5425,6 +5570,13 @@ async function ompFabric(omp) {
5425
5570
  await state.bootstrap(context);
5426
5571
  refreshCodePreviewSettings();
5427
5572
  applyFabricMode();
5573
+ if (!updateCheckStarted) {
5574
+ updateCheckStarted = true;
5575
+ void scheduleFabricUpdateCheck(context, {
5576
+ enabled: state.config.update.check,
5577
+ agentDir: resolveAgentDir()
5578
+ });
5579
+ }
5428
5580
  if (state.shouldEagerlyActivate(context)) await state.ensure(context);
5429
5581
  });
5430
5582
  omp.on("session_tree", async (_event, context) => {
@@ -5595,9 +5747,12 @@ async function ompFabric(omp) {
5595
5747
  reassertToolOwnership();
5596
5748
  const effectiveFullCodeMode = fullCodeMode || schemaMode === "enforce";
5597
5749
  if (!omp.getActiveTools().includes("fabric_exec")) return;
5598
- const skills = event.systemPromptOptions?.skills ?? [];
5750
+ const skills = activeSkills();
5599
5751
  const captureSnapshot = state.cwd ? capturePolicy() : void 0;
5600
- const systemPrompt = effectiveFullCodeMode ? restoreSkillsForFullCodePrompt(event.systemPrompt.join("\n"), skills) : event.systemPrompt.join("\n");
5752
+ const systemPrompt = effectiveFullCodeMode ? restoreSkillsForFullCodePrompt(
5753
+ event.systemPrompt.join("\n"),
5754
+ listableSkills(skills)
5755
+ ) : event.systemPrompt.join("\n");
5601
5756
  const skillReferenceGuidance = effectiveFullCodeMode ? buildSkillReferenceGuidance(event.prompt, skills) : void 0;
5602
5757
  const currentModel = context.model ? `${context.model.provider}/${context.model.id}` : void 0;
5603
5758
  const resolvedGuidance = resolveFabricModelGuidance(state.modelGuidance(), {