openfleet 0.4.1 → 0.4.3

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/index.js CHANGED
@@ -31,38 +31,6 @@ var PATHS = {
31
31
  troubleshooting: path.join(PUBLIC_DIR, "troubleshooting")
32
32
  };
33
33
 
34
- // src/models.ts
35
- var models = {
36
- bedrock: {
37
- sonnet: "amazon-bedrock/anthropic.claude-sonnet-4-6",
38
- opus: "amazon-bedrock/anthropic.claude-opus-4-6-v1",
39
- haiku: "amazon-bedrock/anthropic.claude-haiku-4-5-20251001-v1:0"
40
- },
41
- anthropic: {
42
- sonnet: "anthropic/claude-sonnet-4-6",
43
- opus: "anthropic/claude-opus-4-6",
44
- haiku: "anthropic/claude-haiku-4-5"
45
- },
46
- openai: {
47
- gpt5: "openai/gpt-5.2",
48
- o4Mini: "openai/o4-mini",
49
- o3: "openai/o3"
50
- },
51
- google: {
52
- gemini3Pro: "google/gemini-3-pro-high",
53
- gemini3Flash: "google/gemini-3-flash",
54
- gemini25Pro: "google/gemini-2.5-pro"
55
- },
56
- freeModels: {
57
- minimaxM25: "opencode/minimax-m2.5",
58
- minimaxM25Free: "opencode/minimax-m2.5-free",
59
- bigPickle: "opencode/big-pickle"
60
- }
61
- };
62
- var defaultModel = process.env.OPENFLEET_MODEL ?? models.anthropic.sonnet;
63
- var bigModel = defaultModel;
64
- var fallbackModel = models.freeModels.minimaxM25Free;
65
-
66
34
  // src/agents/architect.ts
67
35
  var SYSTEM_PROMPT = `You are Architect, Planner of the Openfleet.
68
36
 
@@ -125,7 +93,6 @@ at the start of each session. Update it with:
125
93
  var architectAgent = {
126
94
  description: "Openfleet planner",
127
95
  mode: "subagent",
128
- model: defaultModel,
129
96
  prompt: SYSTEM_PROMPT,
130
97
  color: "#BF3907"
131
98
  };
@@ -363,7 +330,6 @@ at the start of each session. Update it with:
363
330
  var builderAgent = {
364
331
  description: "Openfleet engineer - executes the plan",
365
332
  mode: "subagent",
366
- model: defaultModel,
367
333
  prompt: SYSTEM_PROMPT2,
368
334
  color: "#FDDF04"
369
335
  };
@@ -436,7 +402,6 @@ at the start of each session. Use it for:
436
402
  var introspectorAgent = {
437
403
  description: "Introspector - Reflector",
438
404
  mode: "subagent",
439
- model: defaultModel,
440
405
  prompt: SYSTEM_PROMPT3,
441
406
  color: "#C349E9"
442
407
  };
@@ -919,7 +884,6 @@ Good luck!
919
884
  var orchestratorAgent = {
920
885
  description: "Orchestrator of the Openfleet",
921
886
  mode: "primary",
922
- model: bigModel,
923
887
  prompt: SYSTEM_PROMPT4,
924
888
  color: "#35C2CB"
925
889
  };
@@ -991,7 +955,6 @@ at the start of each session. Update it with:
991
955
  var reconAgent = {
992
956
  description: "Recon - Scout",
993
957
  mode: "subagent",
994
- model: defaultModel,
995
958
  prompt: SYSTEM_PROMPT5,
996
959
  color: "#B40F52"
997
960
  };
@@ -1038,7 +1001,6 @@ at the start of each session. Update it with:
1038
1001
  var validatorAgent = {
1039
1002
  description: "Validator - Reviewer",
1040
1003
  mode: "subagent",
1041
- model: defaultModel,
1042
1004
  prompt: SYSTEM_PROMPT6,
1043
1005
  color: "#018D40"
1044
1006
  };
@@ -1075,8 +1037,7 @@ async function sleep(time_ms) {
1075
1037
 
1076
1038
  // src/logger.ts
1077
1039
  import { appendFileSync, existsSync } from "fs";
1078
- import { join as join2 } from "path";
1079
- var LOG_FILE = join2(OPENFLEET_DIR, "openfleet.log");
1040
+ var LOG_FILE = PATHS.logFile;
1080
1041
  var dirVerified = false;
1081
1042
  function writeLog(level, msg, ...args) {
1082
1043
  const timestamp = new Date().toISOString();
@@ -1113,29 +1074,28 @@ Use this tool:
1113
1074
  note: tool.schema.string().optional().describe("Optional note about what was accomplished")
1114
1075
  },
1115
1076
  async execute(_args, context) {
1116
- const { sessionID } = context;
1117
- try {
1118
- const { data: messages } = await ctx.client.session.messages({
1119
- path: { id: sessionID },
1120
- query: { directory: ctx.directory }
1121
- });
1122
- if (!messages || messages.length === 0) {
1123
- return "No messages to save.";
1124
- }
1125
- const lastAssistant = [...messages].reverse().find((m) => m.info.role === "assistant");
1126
- const providerID = lastAssistant?.info.providerID ?? "anthropic";
1127
- const modelID = lastAssistant?.info.modelID ?? "claude-sonnet-4";
1128
- await ctx.client.session.summarize({
1129
- path: { id: sessionID },
1130
- body: { providerID, modelID },
1131
- query: { directory: ctx.directory }
1132
- });
1077
+ const { sessionID, messageID } = context;
1078
+ const { data: messages } = await ctx.client.session.messages({
1079
+ path: { id: sessionID }
1080
+ });
1081
+ const currentMsg = messages?.find((m) => m.info.id === messageID);
1082
+ const info = currentMsg?.info;
1083
+ const providerID = info?.role === "assistant" ? info.providerID : info?.model?.providerID;
1084
+ const modelID = info?.role === "assistant" ? info.modelID : info?.model?.modelID;
1085
+ if (!providerID || !modelID) {
1086
+ logger.error("Cannot determine model for summarization", { sessionID, messageID });
1087
+ return "\u274C Failed to determine model for context compaction.";
1088
+ }
1089
+ ctx.client.session.summarize({
1090
+ path: { id: sessionID },
1091
+ body: { providerID, modelID },
1092
+ query: { directory: ctx.directory }
1093
+ }).then(() => {
1133
1094
  logger.info("Session compacted", { sessionID, providerID, modelID });
1134
- return `\u2705 Context compacted successfully.`;
1135
- } catch (error) {
1095
+ }).catch((error) => {
1136
1096
  logger.error("Failed to compact session", error);
1137
- return `\u274C Failed to compact session: ${error}`;
1138
- }
1097
+ });
1098
+ return `\u2705 Context compaction initiated.`;
1139
1099
  }
1140
1100
  });
1141
1101
  }
@@ -1386,24 +1346,48 @@ import * as fs from "fs";
1386
1346
  import * as path4 from "path";
1387
1347
  import { fileURLToPath } from "url";
1388
1348
  // package.json
1389
- var version = "0.4.0";
1349
+ var version = "0.4.2";
1390
1350
 
1391
1351
  // src/utils/directory-init.ts
1392
1352
  var TEMPLATES_DIR = path4.join(path4.dirname(fileURLToPath(import.meta.url)), "templates", ".openfleet");
1353
+ var BUNDLED_MIGRATIONS_DIR = path4.join(TEMPLATES_DIR, "migrations");
1393
1354
  function initializeDirectories() {
1394
1355
  if (fs.existsSync(OPENFLEET_DIR)) {
1395
1356
  return;
1396
1357
  }
1397
1358
  copyDirectorySync(TEMPLATES_DIR, OPENFLEET_DIR);
1359
+ stampVersion();
1398
1360
  logger.info("Initialized .openfleet directory");
1399
1361
  }
1400
- function checkMigrationNeeded() {
1362
+ function getPendingMigrations() {
1401
1363
  if (!fs.existsSync(OPENFLEET_DIR))
1402
- return false;
1364
+ return [];
1365
+ if (!fs.existsSync(BUNDLED_MIGRATIONS_DIR))
1366
+ return [];
1367
+ const installedVersion = readInstalledVersion();
1368
+ return fs.readdirSync(BUNDLED_MIGRATIONS_DIR).filter((f) => f.endsWith(".md")).map((f) => f.replace(/\.md$/, "")).filter((v) => compareSemver(v, installedVersion) > 0 && compareSemver(v, version) <= 0).sort(compareSemver);
1369
+ }
1370
+ function stampVersion() {
1371
+ fs.writeFileSync(PATHS.versionFile, version);
1372
+ }
1373
+ function readInstalledVersion() {
1403
1374
  if (!fs.existsSync(PATHS.versionFile))
1404
- return true;
1405
- const installedVersion = fs.readFileSync(PATHS.versionFile, "utf-8").trim();
1406
- return installedVersion !== version;
1375
+ return "0.0.0";
1376
+ const raw = fs.readFileSync(PATHS.versionFile, "utf-8").trim();
1377
+ const parts = raw.split(".").map(Number);
1378
+ if (parts.length !== 3 || parts.some(isNaN))
1379
+ return "0.0.0";
1380
+ return raw;
1381
+ }
1382
+ function compareSemver(a, b) {
1383
+ const pa = a.split(".").map(Number);
1384
+ const pb = b.split(".").map(Number);
1385
+ for (let i = 0;i < 3; i++) {
1386
+ const diff = (pa[i] || 0) - (pb[i] || 0);
1387
+ if (diff !== 0)
1388
+ return diff;
1389
+ }
1390
+ return 0;
1407
1391
  }
1408
1392
  function copyDirectorySync(src, dest) {
1409
1393
  fs.mkdirSync(dest, { recursive: true });
@@ -1476,14 +1460,18 @@ var OpenfleetPlugin = async (ctx) => {
1476
1460
  const props = event.properties;
1477
1461
  if (!props?.info?.parentID) {
1478
1462
  setTimeout(async () => {
1479
- if (checkMigrationNeeded()) {
1463
+ const pending = getPendingMigrations();
1464
+ if (pending.length > 0) {
1465
+ const latest = pending[pending.length - 1];
1466
+ const message = pending.length === 1 ? `Run migration for v${latest}` : `${pending.length} migrations pending (v${pending[0]} \u2192 v${latest})`;
1480
1467
  await showToast(ctx, {
1481
1468
  title: "\u26A0\uFE0F Openfleet Migration Required",
1482
- message: "Copy this: 'github.com/scottsus/openfleet/issues/11' to the chat, to migrate to v0.4.0",
1469
+ message,
1483
1470
  variant: "warning",
1484
1471
  duration: 1e4
1485
1472
  });
1486
1473
  } else {
1474
+ stampVersion();
1487
1475
  await showFleetToast(ctx);
1488
1476
  }
1489
1477
  }, 0);
package/dist/models.d.ts CHANGED
@@ -25,7 +25,4 @@ export declare const models: {
25
25
  readonly bigPickle: "opencode/big-pickle";
26
26
  };
27
27
  };
28
- export declare const defaultModel: string;
29
- export declare const bigModel: string;
30
- export declare const smallModel: string;
31
28
  export declare const fallbackModel: "opencode/minimax-m2.5-free";
@@ -1,2 +1,9 @@
1
1
  export declare function initializeDirectories(): void;
2
- export declare function checkMigrationNeeded(): boolean;
2
+ /**
3
+ * Returns pending migration versions between the installed VERSION and current package version.
4
+ *
5
+ * Scans the bundled templates migrations dir (not runtime .openfleet/migrations/)
6
+ * since pre-0.4.0 installs won't have a migrations/ folder at all.
7
+ */
8
+ export declare function getPendingMigrations(): string[];
9
+ export declare function stampVersion(): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openfleet",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
4
4
  "description": "SPARR framework agents + infinite context for OpenCode",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",