@dotobokuri/fleet-console 1.22.1 → 1.24.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/AGENTS.md +41 -255
- package/README.md +8 -0
- package/dist/cli.d.ts +11 -1
- package/dist/cli.mjs +1866 -515
- package/dist/client/assets/{_baseUniq-cap0P4FK.js → _baseUniq-yooYbTgN.js} +1 -1
- package/dist/client/assets/{arc-yBqa09aK.js → arc-D4mme5Ts.js} +1 -1
- package/dist/client/assets/{architectureDiagram-Q4EWVU46-Bug4qdr-.js → architectureDiagram-Q4EWVU46-BAJOviEX.js} +1 -1
- package/dist/client/assets/{blockDiagram-DXYQGD6D-BkiIL2xt.js → blockDiagram-DXYQGD6D-DuObpxQ3.js} +1 -1
- package/dist/client/assets/{c4Diagram-AHTNJAMY-DYY200Al.js → c4Diagram-AHTNJAMY-BOT-SD34.js} +1 -1
- package/dist/client/assets/channel-TZYyAq1v.js +1 -0
- package/dist/client/assets/{chunk-4BX2VUAB-DQKmhVxn.js → chunk-4BX2VUAB-BF_aMTes.js} +1 -1
- package/dist/client/assets/{chunk-4TB4RGXK-DHpmA3Zl.js → chunk-4TB4RGXK-M4brBcnD.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-DeRDuQXE.js → chunk-55IACEB6-CrG-4b2Z.js} +1 -1
- package/dist/client/assets/{chunk-EDXVE4YY-CNpnhSJm.js → chunk-EDXVE4YY-BxDSygH1.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-BXGVABL-.js → chunk-FMBD7UC4-Bh7MEX7E.js} +1 -1
- package/dist/client/assets/{chunk-OYMX7WX6-WbJs4VwZ.js → chunk-OYMX7WX6-DBnBwxer.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-u3BLl6Sl.js → chunk-QZHKN3VN-bjAogQwW.js} +1 -1
- package/dist/client/assets/{chunk-YZCP3GAM-BFESuhuJ.js → chunk-YZCP3GAM-l4FGlk_c.js} +1 -1
- package/dist/client/assets/classDiagram-6PBFFD2Q-Dh6hZUl4.js +1 -0
- package/dist/client/assets/classDiagram-v2-HSJHXN6E-Dh6hZUl4.js +1 -0
- package/dist/client/assets/clone-DgWGnVWH.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-rouOsZjT.js → cose-bilkent-S5V4N54A-Bm5QA4zo.js} +1 -1
- package/dist/client/assets/{dagre-KV5264BT-QCUeCVpM.js → dagre-KV5264BT-PzXQN-5Q.js} +1 -1
- package/dist/client/assets/{diagram-5BDNPKRD-DqerlFb_.js → diagram-5BDNPKRD-KhaAKPtX.js} +1 -1
- package/dist/client/assets/{diagram-G4DWMVQ6-BS3a1YGN.js → diagram-G4DWMVQ6-DBbjfiR8.js} +1 -1
- package/dist/client/assets/{diagram-MMDJMWI5-BeauTcSV.js → diagram-MMDJMWI5-QWro7PRX.js} +1 -1
- package/dist/client/assets/{diagram-TYMM5635-Ci2wLUUE.js → diagram-TYMM5635-B9LqWrbF.js} +1 -1
- package/dist/client/assets/{erDiagram-SMLLAGMA-9MnmiKch.js → erDiagram-SMLLAGMA-b0VkMMN4.js} +1 -1
- package/dist/client/assets/{flowDiagram-DWJPFMVM-CiV9p5EU.js → flowDiagram-DWJPFMVM-edxBAbe6.js} +1 -1
- package/dist/client/assets/{ganttDiagram-T4ZO3ILL-D6oNoENl.js → ganttDiagram-T4ZO3ILL-ks2Gg1_V.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-UUTBAWPF-DESO385F.js → gitGraphDiagram-UUTBAWPF-DymUyYNl.js} +1 -1
- package/dist/client/assets/{graph-BZdl-RHy.js → graph-B-B_mqfh.js} +1 -1
- package/dist/client/assets/index-BgLzfg-v.css +1 -0
- package/dist/client/assets/index-pDnb-q6f.js +380 -0
- package/dist/client/assets/{infoDiagram-42DDH7IO-lc8vZnyi.js → infoDiagram-42DDH7IO-B5iLIYAc.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-UXIWVN3A-BfzvQXhn.js → ishikawaDiagram-UXIWVN3A-DnztLLn7.js} +1 -1
- package/dist/client/assets/{journeyDiagram-VCZTEJTY-BS_Dr0EV.js → journeyDiagram-VCZTEJTY-BKDRfH1Y.js} +1 -1
- package/dist/client/assets/{kanban-definition-6JOO6SKY-Cw7oTQJN.js → kanban-definition-6JOO6SKY-DPB3Phvr.js} +1 -1
- package/dist/client/assets/{layout-ChwcDQm8.js → layout-BEeRhYTG.js} +1 -1
- package/dist/client/assets/{linear-C7GLbmND.js → linear-QzmfWKSq.js} +1 -1
- package/dist/client/assets/{mermaid.core-D9phfpQo.js → mermaid.core-BVka5dgm.js} +4 -4
- package/dist/client/assets/{min-p7Whc_Wi.js → min-CfXk9kSN.js} +1 -1
- package/dist/client/assets/{mindmap-definition-QFDTVHPH-fl_SJKrw.js → mindmap-definition-QFDTVHPH-tGrGhr6Z.js} +1 -1
- package/dist/client/assets/{pieDiagram-DEJITSTG-Btw7ckA5.js → pieDiagram-DEJITSTG-ZRBqRiRK.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-34T5L4WZ-DB4iJlTI.js → quadrantDiagram-34T5L4WZ-VCINZgct.js} +1 -1
- package/dist/client/assets/{requirementDiagram-MS252O5E-hXwV5Nhy.js → requirementDiagram-MS252O5E-DFLzADh3.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-XADWPNL6-DC-fizCk.js → sankeyDiagram-XADWPNL6-BbouN8Ji.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-FGHM5R23-RrfrroR5.js → sequenceDiagram-FGHM5R23-B58_LF0R.js} +1 -1
- package/dist/client/assets/{stateDiagram-FHFEXIEX-q8FUPV_e.js → stateDiagram-FHFEXIEX-pk-OHHuL.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-xsN122JA.js +1 -0
- package/dist/client/assets/{timeline-definition-GMOUNBTQ-tegMd8Od.js → timeline-definition-GMOUNBTQ-4jQdCvaj.js} +1 -1
- package/dist/client/assets/{vennDiagram-DHZGUBPP-CXx5oN2X.js → vennDiagram-DHZGUBPP-CUr1fH6N.js} +1 -1
- package/dist/client/assets/{wardley-RL74JXVD-CxSJ3P_7.js → wardley-RL74JXVD-D0cfvvNA.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-NUSXRM2D-DN1P180Z.js → wardleyDiagram-NUSXRM2D-D0l_Rp_Z.js} +1 -1
- package/dist/client/assets/{xychartDiagram-5P7HB3ND-Dcn9ukv5.js → xychartDiagram-5P7HB3ND-BdR8OEuJ.js} +1 -1
- package/dist/client/index.html +3 -3
- package/dist/desktop-protocol.d.ts +49 -0
- package/dist/desktop-protocol.mjs +99 -0
- package/dist/fleet-plugins/diff/routes.mjs +124 -225
- package/dist/fleet-plugins/skills/routes.mjs +218 -85
- package/dist/fleet-plugins/terminal/routes.mjs +573 -536
- package/package.json +7 -2
- package/dist/client/assets/channel-B3EqY8ya.js +0 -1
- package/dist/client/assets/classDiagram-6PBFFD2Q-BekEZLVJ.js +0 -1
- package/dist/client/assets/classDiagram-v2-HSJHXN6E-BekEZLVJ.js +0 -1
- package/dist/client/assets/clone-CsVi9-Ni.js +0 -1
- package/dist/client/assets/index-BKpCMFrm.js +0 -380
- package/dist/client/assets/index-cg8Uxys9.css +0 -1
- package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-BErzXGq7.js +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import * as fs2 from 'fs';
|
|
3
|
-
import fs2__default, { existsSync, accessSync, constants, mkdtempSync, writeFileSync, mkdirSync, rmSync, chmodSync, renameSync, readdirSync,
|
|
4
|
-
import * as
|
|
5
|
-
import
|
|
3
|
+
import fs2__default, { existsSync, readFileSync, accessSync, constants, mkdtempSync, writeFileSync, mkdirSync, rmSync, chmodSync, renameSync, readdirSync, openSync, closeSync, realpathSync, fstatSync, lstatSync, unlinkSync, statSync } from 'fs';
|
|
4
|
+
import * as path28 from 'path';
|
|
5
|
+
import path28__default, { dirname } from 'path';
|
|
6
6
|
import * as os3 from 'os';
|
|
7
7
|
import os3__default, { homedir } from 'os';
|
|
8
8
|
import crypto4, { createHash, randomUUID } from 'crypto';
|
|
@@ -25,22 +25,22 @@ var __export = (target, all) => {
|
|
|
25
25
|
function definePlugin(definition) {
|
|
26
26
|
return definition;
|
|
27
27
|
}
|
|
28
|
-
function registerRouter(ctx,
|
|
29
|
-
ctx.registerRouter(normalizePath(
|
|
28
|
+
function registerRouter(ctx, path43, handler) {
|
|
29
|
+
ctx.registerRouter(normalizePath(path43), handler);
|
|
30
30
|
}
|
|
31
|
-
function registerWsHandler(ctx,
|
|
32
|
-
ctx.registerWsHandler(normalizePath(
|
|
31
|
+
function registerWsHandler(ctx, path43, handler) {
|
|
32
|
+
ctx.registerWsHandler(normalizePath(path43), handler);
|
|
33
33
|
}
|
|
34
34
|
function registerLaunchCatalog(ctx, provider) {
|
|
35
35
|
return ctx.host.operations.registerLaunchCatalog(ctx.pluginId, provider);
|
|
36
36
|
}
|
|
37
|
-
function normalizePath(
|
|
38
|
-
if (
|
|
39
|
-
return
|
|
37
|
+
function normalizePath(path43) {
|
|
38
|
+
if (path43.length === 0 || path43 === "/") return "/";
|
|
39
|
+
return path43;
|
|
40
40
|
}
|
|
41
41
|
var FLEET_DATA_DIR_NAME = ".fleet";
|
|
42
42
|
function getFleetDataDir() {
|
|
43
|
-
return
|
|
43
|
+
return path28.join(os3.homedir(), FLEET_DATA_DIR_NAME);
|
|
44
44
|
}
|
|
45
45
|
var SECURE_DIR_MODE = 448;
|
|
46
46
|
var SECURE_FILE_MODE = 384;
|
|
@@ -128,7 +128,7 @@ function cleanupTempFiles(dir, prefix, minAgeMs, now) {
|
|
|
128
128
|
if (!entry.startsWith(prefix)) {
|
|
129
129
|
continue;
|
|
130
130
|
}
|
|
131
|
-
const tempPath =
|
|
131
|
+
const tempPath = path28.join(dir, entry);
|
|
132
132
|
try {
|
|
133
133
|
const stat3 = fs2.lstatSync(tempPath);
|
|
134
134
|
if (stat3?.isFile() && !stat3.isSymbolicLink() && now - stat3.mtimeMs >= minAgeMs) {
|
|
@@ -234,7 +234,7 @@ function writeLockOwner(lockDir, ownerFileName, startedAt) {
|
|
|
234
234
|
hostname: os3.hostname(),
|
|
235
235
|
startedAt
|
|
236
236
|
};
|
|
237
|
-
const ownerPath =
|
|
237
|
+
const ownerPath = path28.join(lockDir, ownerFileName);
|
|
238
238
|
try {
|
|
239
239
|
fs2.writeFileSync(ownerPath, JSON.stringify(owner), { encoding: "utf-8", mode: 384 });
|
|
240
240
|
} catch (error51) {
|
|
@@ -243,7 +243,7 @@ function writeLockOwner(lockDir, ownerFileName, startedAt) {
|
|
|
243
243
|
}
|
|
244
244
|
}
|
|
245
245
|
function readLockOwner(lockDir, ownerFileName) {
|
|
246
|
-
const ownerPath =
|
|
246
|
+
const ownerPath = path28.join(lockDir, ownerFileName);
|
|
247
247
|
try {
|
|
248
248
|
return sanitizeLockOwner(JSON.parse(fs2.readFileSync(ownerPath, "utf-8")));
|
|
249
249
|
} catch (error51) {
|
|
@@ -320,7 +320,7 @@ function readAuthStoreFile(filePath) {
|
|
|
320
320
|
}
|
|
321
321
|
|
|
322
322
|
// ../../packages/core-infra/src/auth/auth-storage.ts
|
|
323
|
-
var DEFAULT_AUTH_PATH =
|
|
323
|
+
var DEFAULT_AUTH_PATH = path28.join(getFleetDataDir(), "auth.json");
|
|
324
324
|
var AUTH_LOCK_OWNER_FILE_NAME = "owner.json";
|
|
325
325
|
var AUTH_LOCK_TIMEOUT_MS = 5e3;
|
|
326
326
|
function createAuthService(deps = {}) {
|
|
@@ -376,7 +376,7 @@ function createAuthService(deps = {}) {
|
|
|
376
376
|
}
|
|
377
377
|
},
|
|
378
378
|
async setApiKey(providerId, key) {
|
|
379
|
-
const dir =
|
|
379
|
+
const dir = path28.dirname(authPath);
|
|
380
380
|
ensureSafeDirectory(dir);
|
|
381
381
|
withAuthLock(authPath, lockDir, () => {
|
|
382
382
|
const data = fs2.existsSync(authPath) ? readAuthStoreFile(authPath) : {};
|
|
@@ -411,7 +411,7 @@ function createDurableJsonStore(deps) {
|
|
|
411
411
|
const now = deps.now ?? (() => Date.now());
|
|
412
412
|
const mode = SECURE_FILE_MODE ;
|
|
413
413
|
const minAgeMs = deps.tempCleanupMinAgeMs ?? DEFAULT_TEMP_FILE_MIN_AGE_MS;
|
|
414
|
-
const dir =
|
|
414
|
+
const dir = path28.dirname(deps.filePath);
|
|
415
415
|
return {
|
|
416
416
|
path: deps.filePath,
|
|
417
417
|
load() {
|
|
@@ -495,8 +495,8 @@ var LOCK_OWNER_FILE_NAME = "owner";
|
|
|
495
495
|
var TEMP_FILE_PREFIX = `.tmp-${GLOBAL_OPTIONS_FILE_NAME}-`;
|
|
496
496
|
function createGlobalOptionsStore(deps = {}) {
|
|
497
497
|
const dataDir = deps.dataDir ?? getFleetDataDir();
|
|
498
|
-
const optionsPath =
|
|
499
|
-
const lockDir =
|
|
498
|
+
const optionsPath = path28.join(dataDir, GLOBAL_OPTIONS_FILE_NAME);
|
|
499
|
+
const lockDir = path28.join(dataDir, LOCK_DIR_NAME);
|
|
500
500
|
const store2 = createDurableJsonStore({
|
|
501
501
|
filePath: optionsPath,
|
|
502
502
|
lockDir,
|
|
@@ -529,10 +529,11 @@ function sanitizeGlobalOptionsData(value) {
|
|
|
529
529
|
}
|
|
530
530
|
const data = {
|
|
531
531
|
version: GLOBAL_OPTIONS_VERSION,
|
|
532
|
-
...typeof value.enableMetaphor === "boolean" ? { enableMetaphor: value.enableMetaphor } : {}
|
|
532
|
+
...typeof value.enableMetaphor === "boolean" ? { enableMetaphor: value.enableMetaphor } : {},
|
|
533
|
+
...value.codexLaunchMode === "acp" || value.codexLaunchMode === "app-server" ? { codexLaunchMode: value.codexLaunchMode } : {}
|
|
533
534
|
};
|
|
534
|
-
const allowedKeys = /* @__PURE__ */ new Set(["version", "enableMetaphor"]);
|
|
535
|
-
const changed = Object.keys(value).some((key) => !allowedKeys.has(key)) || "enableMetaphor" in value && typeof value.enableMetaphor !== "boolean";
|
|
535
|
+
const allowedKeys = /* @__PURE__ */ new Set(["version", "enableMetaphor", "codexLaunchMode"]);
|
|
536
|
+
const changed = Object.keys(value).some((key) => !allowedKeys.has(key)) || "enableMetaphor" in value && typeof value.enableMetaphor !== "boolean" || "codexLaunchMode" in value && value.codexLaunchMode !== "acp" && value.codexLaunchMode !== "app-server";
|
|
536
537
|
return { data, changed };
|
|
537
538
|
}
|
|
538
539
|
function isRecord(value) {
|
|
@@ -1398,10 +1399,10 @@ function mergeDefs(...defs) {
|
|
|
1398
1399
|
function cloneDef(schema) {
|
|
1399
1400
|
return mergeDefs(schema._zod.def);
|
|
1400
1401
|
}
|
|
1401
|
-
function getElementAtPath(obj,
|
|
1402
|
-
if (!
|
|
1402
|
+
function getElementAtPath(obj, path43) {
|
|
1403
|
+
if (!path43)
|
|
1403
1404
|
return obj;
|
|
1404
|
-
return
|
|
1405
|
+
return path43.reduce((acc, key) => acc?.[key], obj);
|
|
1405
1406
|
}
|
|
1406
1407
|
function promiseAllObject(promisesObj) {
|
|
1407
1408
|
const keys = Object.keys(promisesObj);
|
|
@@ -1810,11 +1811,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
1810
1811
|
}
|
|
1811
1812
|
return false;
|
|
1812
1813
|
}
|
|
1813
|
-
function prefixIssues(
|
|
1814
|
+
function prefixIssues(path43, issues) {
|
|
1814
1815
|
return issues.map((iss) => {
|
|
1815
1816
|
var _a3;
|
|
1816
1817
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
1817
|
-
iss.path.unshift(
|
|
1818
|
+
iss.path.unshift(path43);
|
|
1818
1819
|
return iss;
|
|
1819
1820
|
});
|
|
1820
1821
|
}
|
|
@@ -1961,16 +1962,16 @@ function flattenError(error51, mapper = (issue3) => issue3.message) {
|
|
|
1961
1962
|
}
|
|
1962
1963
|
function formatError(error51, mapper = (issue3) => issue3.message) {
|
|
1963
1964
|
const fieldErrors = { _errors: [] };
|
|
1964
|
-
const processError = (error52,
|
|
1965
|
+
const processError = (error52, path43 = []) => {
|
|
1965
1966
|
for (const issue3 of error52.issues) {
|
|
1966
1967
|
if (issue3.code === "invalid_union" && issue3.errors.length) {
|
|
1967
|
-
issue3.errors.map((issues) => processError({ issues }, [...
|
|
1968
|
+
issue3.errors.map((issues) => processError({ issues }, [...path43, ...issue3.path]));
|
|
1968
1969
|
} else if (issue3.code === "invalid_key") {
|
|
1969
|
-
processError({ issues: issue3.issues }, [...
|
|
1970
|
+
processError({ issues: issue3.issues }, [...path43, ...issue3.path]);
|
|
1970
1971
|
} else if (issue3.code === "invalid_element") {
|
|
1971
|
-
processError({ issues: issue3.issues }, [...
|
|
1972
|
+
processError({ issues: issue3.issues }, [...path43, ...issue3.path]);
|
|
1972
1973
|
} else {
|
|
1973
|
-
const fullpath = [...
|
|
1974
|
+
const fullpath = [...path43, ...issue3.path];
|
|
1974
1975
|
if (fullpath.length === 0) {
|
|
1975
1976
|
fieldErrors._errors.push(mapper(issue3));
|
|
1976
1977
|
} else {
|
|
@@ -1997,17 +1998,17 @@ function formatError(error51, mapper = (issue3) => issue3.message) {
|
|
|
1997
1998
|
}
|
|
1998
1999
|
function treeifyError(error51, mapper = (issue3) => issue3.message) {
|
|
1999
2000
|
const result = { errors: [] };
|
|
2000
|
-
const processError = (error52,
|
|
2001
|
+
const processError = (error52, path43 = []) => {
|
|
2001
2002
|
var _a3, _b;
|
|
2002
2003
|
for (const issue3 of error52.issues) {
|
|
2003
2004
|
if (issue3.code === "invalid_union" && issue3.errors.length) {
|
|
2004
|
-
issue3.errors.map((issues) => processError({ issues }, [...
|
|
2005
|
+
issue3.errors.map((issues) => processError({ issues }, [...path43, ...issue3.path]));
|
|
2005
2006
|
} else if (issue3.code === "invalid_key") {
|
|
2006
|
-
processError({ issues: issue3.issues }, [...
|
|
2007
|
+
processError({ issues: issue3.issues }, [...path43, ...issue3.path]);
|
|
2007
2008
|
} else if (issue3.code === "invalid_element") {
|
|
2008
|
-
processError({ issues: issue3.issues }, [...
|
|
2009
|
+
processError({ issues: issue3.issues }, [...path43, ...issue3.path]);
|
|
2009
2010
|
} else {
|
|
2010
|
-
const fullpath = [...
|
|
2011
|
+
const fullpath = [...path43, ...issue3.path];
|
|
2011
2012
|
if (fullpath.length === 0) {
|
|
2012
2013
|
result.errors.push(mapper(issue3));
|
|
2013
2014
|
continue;
|
|
@@ -2039,8 +2040,8 @@ function treeifyError(error51, mapper = (issue3) => issue3.message) {
|
|
|
2039
2040
|
}
|
|
2040
2041
|
function toDotPath(_path) {
|
|
2041
2042
|
const segs = [];
|
|
2042
|
-
const
|
|
2043
|
-
for (const seg of
|
|
2043
|
+
const path43 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
2044
|
+
for (const seg of path43) {
|
|
2044
2045
|
if (typeof seg === "number")
|
|
2045
2046
|
segs.push(`[${seg}]`);
|
|
2046
2047
|
else if (typeof seg === "symbol")
|
|
@@ -14704,13 +14705,13 @@ function resolveRef(ref, ctx) {
|
|
|
14704
14705
|
if (!ref.startsWith("#")) {
|
|
14705
14706
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
14706
14707
|
}
|
|
14707
|
-
const
|
|
14708
|
-
if (
|
|
14708
|
+
const path43 = ref.slice(1).split("/").filter(Boolean);
|
|
14709
|
+
if (path43.length === 0) {
|
|
14709
14710
|
return ctx.rootSchema;
|
|
14710
14711
|
}
|
|
14711
14712
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
14712
|
-
if (
|
|
14713
|
-
const key =
|
|
14713
|
+
if (path43[0] === defsKey) {
|
|
14714
|
+
const key = path43[1];
|
|
14714
14715
|
if (!key || !ctx.defs[key]) {
|
|
14715
14716
|
throw new Error(`Reference not found: ${ref}`);
|
|
14716
14717
|
}
|
|
@@ -18883,7 +18884,7 @@ function createChildEnv(env, overlay) {
|
|
|
18883
18884
|
return child;
|
|
18884
18885
|
}
|
|
18885
18886
|
function wrapWindowsShim(resolved, env, platform) {
|
|
18886
|
-
if (platform !== "win32" || !WINDOWS_SHIM_EXTENSIONS.has(
|
|
18887
|
+
if (platform !== "win32" || !WINDOWS_SHIM_EXTENSIONS.has(path28__default.extname(resolved).toLowerCase())) {
|
|
18887
18888
|
return { bin: resolved, prefixArgs: [] };
|
|
18888
18889
|
}
|
|
18889
18890
|
rejectCmdExpansionSensitiveShim(resolved);
|
|
@@ -18901,13 +18902,13 @@ function forceWindowsArgQuoting(value) {
|
|
|
18901
18902
|
return `${value} `;
|
|
18902
18903
|
}
|
|
18903
18904
|
function findOnPath(bin, pathValue, pathExts, platform) {
|
|
18904
|
-
const pathSeparator = platform === "win32" ? WINDOWS_PATH_SEPARATOR :
|
|
18905
|
-
if (hasPathSeparator(bin, platform) ||
|
|
18905
|
+
const pathSeparator = platform === "win32" ? WINDOWS_PATH_SEPARATOR : path28__default.delimiter;
|
|
18906
|
+
if (hasPathSeparator(bin, platform) || path28__default.isAbsolute(bin)) {
|
|
18906
18907
|
return resolveWithExtensions(bin, pathExts, platform);
|
|
18907
18908
|
}
|
|
18908
18909
|
for (const entry of pathValue.split(pathSeparator)) {
|
|
18909
18910
|
const searchDir = entry.length === 0 ? "." : entry;
|
|
18910
|
-
const candidate = resolveWithExtensions(
|
|
18911
|
+
const candidate = resolveWithExtensions(path28__default.join(searchDir, bin), pathExts, platform);
|
|
18911
18912
|
if (candidate) {
|
|
18912
18913
|
return candidate;
|
|
18913
18914
|
}
|
|
@@ -18915,7 +18916,7 @@ function findOnPath(bin, pathValue, pathExts, platform) {
|
|
|
18915
18916
|
return void 0;
|
|
18916
18917
|
}
|
|
18917
18918
|
function resolveWithExtensions(candidate, pathExts, platform) {
|
|
18918
|
-
if (platform !== "win32" ||
|
|
18919
|
+
if (platform !== "win32" || path28__default.extname(candidate).length > 0) {
|
|
18919
18920
|
return isAccessibleExecutable(candidate, platform) ? candidate : void 0;
|
|
18920
18921
|
}
|
|
18921
18922
|
for (const ext of pathExts) {
|
|
@@ -20329,11 +20330,24 @@ function getYoloModeId(cli) {
|
|
|
20329
20330
|
return "yolo";
|
|
20330
20331
|
}
|
|
20331
20332
|
}
|
|
20332
|
-
function
|
|
20333
|
-
|
|
20334
|
-
|
|
20333
|
+
function buildCodexConfigEnv(systemPrompt, configOverrides, baseConfigJson) {
|
|
20334
|
+
const map2 = parseBaseConfigMap(baseConfigJson);
|
|
20335
|
+
for (const override of configOverrides ?? []) {
|
|
20336
|
+
const eqIndex = override.indexOf("=");
|
|
20337
|
+
if (eqIndex < 0) {
|
|
20338
|
+
continue;
|
|
20339
|
+
}
|
|
20340
|
+
const key = override.slice(0, eqIndex);
|
|
20341
|
+
const rawValue = override.slice(eqIndex + 1);
|
|
20342
|
+
assignNestedKey(map2, key, parseOverrideValue(rawValue));
|
|
20335
20343
|
}
|
|
20336
|
-
|
|
20344
|
+
if (systemPrompt) {
|
|
20345
|
+
map2.developer_instructions = systemPrompt;
|
|
20346
|
+
}
|
|
20347
|
+
if (Object.keys(map2).length === 0) {
|
|
20348
|
+
return void 0;
|
|
20349
|
+
}
|
|
20350
|
+
return JSON.stringify(map2);
|
|
20337
20351
|
}
|
|
20338
20352
|
function buildConfigOverrideArgs(overrides) {
|
|
20339
20353
|
return overrides.flatMap((override) => ["-c", override]);
|
|
@@ -20361,27 +20375,44 @@ function mcpServerConfigsToAcp(servers) {
|
|
|
20361
20375
|
headers: server.headers ?? []
|
|
20362
20376
|
}));
|
|
20363
20377
|
}
|
|
20364
|
-
function
|
|
20365
|
-
|
|
20366
|
-
|
|
20367
|
-
|
|
20368
|
-
|
|
20369
|
-
|
|
20370
|
-
|
|
20371
|
-
|
|
20372
|
-
return "\\n";
|
|
20373
|
-
case "\f":
|
|
20374
|
-
return "\\f";
|
|
20375
|
-
case "\r":
|
|
20376
|
-
return "\\r";
|
|
20377
|
-
case '"':
|
|
20378
|
-
return '\\"';
|
|
20379
|
-
case "\\":
|
|
20380
|
-
return "\\\\";
|
|
20381
|
-
default:
|
|
20382
|
-
return `\\u${char.charCodeAt(0).toString(16).padStart(4, "0")}`;
|
|
20378
|
+
function parseBaseConfigMap(baseConfigJson) {
|
|
20379
|
+
if (!baseConfigJson) {
|
|
20380
|
+
return {};
|
|
20381
|
+
}
|
|
20382
|
+
try {
|
|
20383
|
+
const parsed = JSON.parse(baseConfigJson);
|
|
20384
|
+
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
|
|
20385
|
+
return parsed;
|
|
20383
20386
|
}
|
|
20384
|
-
}
|
|
20387
|
+
} catch {
|
|
20388
|
+
}
|
|
20389
|
+
return {};
|
|
20390
|
+
}
|
|
20391
|
+
function parseOverrideValue(raw) {
|
|
20392
|
+
try {
|
|
20393
|
+
return JSON.parse(raw);
|
|
20394
|
+
} catch {
|
|
20395
|
+
if (raw.length >= 2 && raw.startsWith('"') && raw.endsWith('"')) {
|
|
20396
|
+
return raw.slice(1, -1);
|
|
20397
|
+
}
|
|
20398
|
+
return raw;
|
|
20399
|
+
}
|
|
20400
|
+
}
|
|
20401
|
+
function assignNestedKey(target, dottedKey, value) {
|
|
20402
|
+
const segments = dottedKey.split(".");
|
|
20403
|
+
let cursor = target;
|
|
20404
|
+
for (let i = 0; i < segments.length - 1; i += 1) {
|
|
20405
|
+
const segment = segments[i];
|
|
20406
|
+
const existing = cursor[segment];
|
|
20407
|
+
if (typeof existing === "object" && existing !== null && !Array.isArray(existing)) {
|
|
20408
|
+
cursor = existing;
|
|
20409
|
+
} else {
|
|
20410
|
+
const nested = {};
|
|
20411
|
+
cursor[segment] = nested;
|
|
20412
|
+
cursor = nested;
|
|
20413
|
+
}
|
|
20414
|
+
}
|
|
20415
|
+
cursor[segments[segments.length - 1]] = value;
|
|
20385
20416
|
}
|
|
20386
20417
|
|
|
20387
20418
|
// ../../packages/core-unified-agent/src/detector/CliDetector.ts
|
|
@@ -21642,12 +21673,12 @@ var CodexAppServerConnection = class extends BaseConnection {
|
|
|
21642
21673
|
);
|
|
21643
21674
|
}
|
|
21644
21675
|
findRolloutPathForThreadId(threadId) {
|
|
21645
|
-
const codexHome = this.codexHome ?? this.env.CODEX_HOME ??
|
|
21676
|
+
const codexHome = this.codexHome ?? this.env.CODEX_HOME ?? path28.join(this.env.HOME ?? "", ".codex");
|
|
21646
21677
|
if (!codexHome) {
|
|
21647
21678
|
return null;
|
|
21648
21679
|
}
|
|
21649
21680
|
for (const rootName of ["sessions", "archived_sessions"]) {
|
|
21650
|
-
const found = findRolloutPath(
|
|
21681
|
+
const found = findRolloutPath(path28.join(codexHome, rootName), threadId);
|
|
21651
21682
|
if (found) {
|
|
21652
21683
|
return found;
|
|
21653
21684
|
}
|
|
@@ -21758,7 +21789,7 @@ function findRolloutPath(root, threadId) {
|
|
|
21758
21789
|
return null;
|
|
21759
21790
|
}
|
|
21760
21791
|
for (const entry of fs2.readdirSync(root, { withFileTypes: true })) {
|
|
21761
|
-
const entryPath =
|
|
21792
|
+
const entryPath = path28.join(root, entry.name);
|
|
21762
21793
|
if (entry.isDirectory()) {
|
|
21763
21794
|
const found = findRolloutPath(entryPath, threadId);
|
|
21764
21795
|
if (found) {
|
|
@@ -21776,13 +21807,11 @@ function findRolloutPath(root, threadId) {
|
|
|
21776
21807
|
// ../../packages/core-unified-agent/src/client/UnifiedCodexAgentClient.ts
|
|
21777
21808
|
var CODEX_TURN_LEVEL_CONFIG_KEYS = /* @__PURE__ */ new Set(["effort", "model"]);
|
|
21778
21809
|
var CODEX_THREAD_POLICY_CONFIG_KEYS = /* @__PURE__ */ new Set(["approvalPolicy", "sandbox"]);
|
|
21779
|
-
var CODEX_ACP_PROMPT_FALLBACK = process.platform === "win32";
|
|
21780
21810
|
var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
21781
21811
|
connection = null;
|
|
21782
21812
|
sessionId = null;
|
|
21783
21813
|
sessionCwd = null;
|
|
21784
21814
|
currentSystemPrompt = null;
|
|
21785
|
-
firstPromptPending = null;
|
|
21786
21815
|
pendingOverrides = null;
|
|
21787
21816
|
detector = new CliDetector();
|
|
21788
21817
|
on(event, listener) {
|
|
@@ -21803,9 +21832,10 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
|
21803
21832
|
throw new Error("UnifiedCodexAgentClient\uB294 codex CLI\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4.");
|
|
21804
21833
|
}
|
|
21805
21834
|
this.validateModelEffort(options.model, options.effort);
|
|
21806
|
-
{
|
|
21835
|
+
if (shouldUseCodexAcp(options)) {
|
|
21807
21836
|
return this.connectAcp(options);
|
|
21808
21837
|
}
|
|
21838
|
+
return this.connectAppServer(options);
|
|
21809
21839
|
}
|
|
21810
21840
|
async connectAppServer(options) {
|
|
21811
21841
|
const backend = getBackendConfig("codex");
|
|
@@ -21874,22 +21904,17 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
|
21874
21904
|
async connectAcp(options) {
|
|
21875
21905
|
const cleanEnv = cleanEnvironment(process.env, options.env);
|
|
21876
21906
|
const spawnConfig = createSpawnConfig("codex", options);
|
|
21877
|
-
const
|
|
21878
|
-
|
|
21879
|
-
|
|
21880
|
-
|
|
21881
|
-
|
|
21882
|
-
void 0,
|
|
21883
|
-
void 0,
|
|
21884
|
-
developerInstructions
|
|
21885
|
-
)
|
|
21886
|
-
];
|
|
21907
|
+
const codexConfigEnv = buildCodexConfigEnv(
|
|
21908
|
+
options.systemPrompt,
|
|
21909
|
+
options.configOverrides,
|
|
21910
|
+
cleanEnv.CODEX_CONFIG
|
|
21911
|
+
);
|
|
21887
21912
|
const connection = new AcpConnection({
|
|
21888
21913
|
command: spawnConfig.command,
|
|
21889
|
-
args,
|
|
21914
|
+
args: spawnConfig.args,
|
|
21890
21915
|
cliType: "codex",
|
|
21891
21916
|
cwd: options.cwd,
|
|
21892
|
-
env: { ...cleanEnv },
|
|
21917
|
+
env: { ...cleanEnv, ...codexConfigEnv ? { CODEX_CONFIG: codexConfigEnv } : {} },
|
|
21893
21918
|
requestTimeout: options.timeout ?? 6e5,
|
|
21894
21919
|
initTimeout: options.timeout ?? 6e4,
|
|
21895
21920
|
promptIdleTimeout: options.promptIdleTimeout ?? 6e5,
|
|
@@ -21986,17 +22011,7 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
|
21986
22011
|
if (!this.sessionId) {
|
|
21987
22012
|
throw new Error("\uC5F0\uACB0\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
|
|
21988
22013
|
}
|
|
21989
|
-
|
|
21990
|
-
if (!systemPrompt) {
|
|
21991
|
-
return this.connection.sendPrompt(this.sessionId, content);
|
|
21992
|
-
}
|
|
21993
|
-
const userBlocks = typeof content === "string" ? [{ type: "text", text: content }] : content;
|
|
21994
|
-
const response = await this.connection.sendPrompt(this.sessionId, [
|
|
21995
|
-
{ type: "text", text: systemPrompt },
|
|
21996
|
-
...userBlocks
|
|
21997
|
-
]);
|
|
21998
|
-
this.firstPromptPending = null;
|
|
21999
|
-
return response;
|
|
22014
|
+
return this.connection.sendPrompt(this.sessionId, content);
|
|
22000
22015
|
}
|
|
22001
22016
|
this.applyPendingOverrides();
|
|
22002
22017
|
const input = typeof content === "string" ? [{ type: "text", text: content, text_elements: [] }] : content.map((block) => "text" in block ? { type: "text", text: block.text, text_elements: [] } : { type: "text", text: JSON.stringify(block), text_elements: [] });
|
|
@@ -22078,8 +22093,6 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
|
22078
22093
|
mcpServers: this.resolveAcpMcpServers(mcpServers)
|
|
22079
22094
|
});
|
|
22080
22095
|
this.sessionId = sessionId;
|
|
22081
|
-
this.currentSystemPrompt = null;
|
|
22082
|
-
this.firstPromptPending = null;
|
|
22083
22096
|
return;
|
|
22084
22097
|
}
|
|
22085
22098
|
if (mcpServers?.length) {
|
|
@@ -22116,7 +22129,6 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
|
22116
22129
|
const session = await this.connection.reconnectSession(targetCwd);
|
|
22117
22130
|
this.sessionId = session.sessionId;
|
|
22118
22131
|
this.sessionCwd = targetCwd;
|
|
22119
|
-
this.firstPromptPending = this.currentSystemPrompt;
|
|
22120
22132
|
return {
|
|
22121
22133
|
cli: "codex",
|
|
22122
22134
|
protocol: "acp",
|
|
@@ -22144,7 +22156,6 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
|
22144
22156
|
this.sessionId = session.sessionId;
|
|
22145
22157
|
this.sessionCwd = options.cwd;
|
|
22146
22158
|
this.currentSystemPrompt = options.systemPrompt ?? null;
|
|
22147
|
-
this.firstPromptPending = CODEX_ACP_PROMPT_FALLBACK && !options.sessionId ? options.systemPrompt ?? null : null;
|
|
22148
22159
|
this.pendingOverrides = {
|
|
22149
22160
|
turnConfig: {},
|
|
22150
22161
|
threadConfig: {}
|
|
@@ -22162,7 +22173,6 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
|
22162
22173
|
this.sessionId = null;
|
|
22163
22174
|
this.sessionCwd = null;
|
|
22164
22175
|
this.currentSystemPrompt = null;
|
|
22165
|
-
this.firstPromptPending = null;
|
|
22166
22176
|
this.pendingOverrides = null;
|
|
22167
22177
|
}
|
|
22168
22178
|
validateModelEffort(modelId, effort) {
|
|
@@ -22373,9 +22383,8 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
|
22373
22383
|
return "read-only";
|
|
22374
22384
|
}
|
|
22375
22385
|
}
|
|
22376
|
-
buildStartupConfigArgs(overrides, servers, modeMapping
|
|
22386
|
+
buildStartupConfigArgs(overrides, servers, modeMapping) {
|
|
22377
22387
|
const configArgs = [
|
|
22378
|
-
...buildCodexDeveloperInstructionConfig(developerInstructions),
|
|
22379
22388
|
...modeMapping ? [
|
|
22380
22389
|
`approval_policy="${modeMapping.approvalPolicy}"`,
|
|
22381
22390
|
`sandbox_mode="${modeMapping.sandbox}"`
|
|
@@ -22464,6 +22473,11 @@ var UnifiedCodexAgentClient = class extends EventEmitter {
|
|
|
22464
22473
|
return patterns.some((pattern) => pattern.test(text));
|
|
22465
22474
|
}
|
|
22466
22475
|
};
|
|
22476
|
+
function shouldUseCodexAcp(options) {
|
|
22477
|
+
const value = options.env?.CODEX_USE_ACP ?? process.env.CODEX_USE_ACP;
|
|
22478
|
+
const normalized = value?.trim().toLowerCase();
|
|
22479
|
+
return normalized !== "false" && normalized !== "0";
|
|
22480
|
+
}
|
|
22467
22481
|
var UnifiedCursorAgentClient = class extends EventEmitter {
|
|
22468
22482
|
connection = null;
|
|
22469
22483
|
sessionId = null;
|
|
@@ -25085,7 +25099,7 @@ function readRawCarriersOrDefaultStore() {
|
|
|
25085
25099
|
return readCarriers();
|
|
25086
25100
|
}
|
|
25087
25101
|
function getCarriersFilePath() {
|
|
25088
|
-
return
|
|
25102
|
+
return path28.join(resolveStoreDir(), FILENAME);
|
|
25089
25103
|
}
|
|
25090
25104
|
function updateCarriers(mutator) {
|
|
25091
25105
|
withStoreLock(() => {
|
|
@@ -25099,7 +25113,7 @@ function updateCarriers(mutator) {
|
|
|
25099
25113
|
function withStoreLock(operation) {
|
|
25100
25114
|
const dir = resolveStoreDir();
|
|
25101
25115
|
ensureSafeDirectory(dir);
|
|
25102
|
-
const lockDir =
|
|
25116
|
+
const lockDir = path28.join(dir, LOCK_DIRNAME);
|
|
25103
25117
|
return withDirectoryLock(
|
|
25104
25118
|
{ lockDir, ownerFileName: LOCK_OWNER_FILENAME },
|
|
25105
25119
|
operation
|
|
@@ -25112,7 +25126,7 @@ function readCarriers() {
|
|
|
25112
25126
|
return readCarriersFromDir(resolveStoreDir());
|
|
25113
25127
|
}
|
|
25114
25128
|
function readCarriersFromDir(dir) {
|
|
25115
|
-
const filePath =
|
|
25129
|
+
const filePath = path28.join(dir, FILENAME);
|
|
25116
25130
|
let fd;
|
|
25117
25131
|
try {
|
|
25118
25132
|
const stat3 = fs2.lstatSync(filePath);
|
|
@@ -25141,7 +25155,7 @@ function recordLastLocalWriteFingerprint(filePath, generation) {
|
|
|
25141
25155
|
}
|
|
25142
25156
|
function writeCarriers(s) {
|
|
25143
25157
|
const dir = resolveStoreDir();
|
|
25144
|
-
const filePath =
|
|
25158
|
+
const filePath = path28.join(dir, FILENAME);
|
|
25145
25159
|
const next = serializeFleetCarriers(s);
|
|
25146
25160
|
writeAtomicSync(filePath, `${JSON.stringify(next, null, 2)}
|
|
25147
25161
|
`, { fsync: false, mode: 420 });
|
|
@@ -25166,7 +25180,7 @@ function sanitizeFleetCarriers(value) {
|
|
|
25166
25180
|
}
|
|
25167
25181
|
function unlinkStaleSubagentModeFile(dir) {
|
|
25168
25182
|
try {
|
|
25169
|
-
fs2.unlinkSync(
|
|
25183
|
+
fs2.unlinkSync(path28.join(dir, STALE_SUBAGENT_MODE_FILENAME));
|
|
25170
25184
|
} catch {
|
|
25171
25185
|
}
|
|
25172
25186
|
}
|
|
@@ -25722,7 +25736,7 @@ var CHRONICLE_DEFAULTS = {
|
|
|
25722
25736
|
};
|
|
25723
25737
|
var CARRIER_METADATA = {
|
|
25724
25738
|
// ── Tier 1: Routing ──
|
|
25725
|
-
title: "
|
|
25739
|
+
title: "Chief Knowledge Officer",
|
|
25726
25740
|
summary: "Documentation steward across two surfaces: codebase markdown (AGENTS.md/README/CHANGELOG/inline docs) and Fleet Wiki entries proposed via the wiki patch queue.",
|
|
25727
25741
|
category: "operations",
|
|
25728
25742
|
whenToUse: [
|
|
@@ -25735,7 +25749,7 @@ var CARRIER_METADATA = {
|
|
|
25735
25749
|
"before implementation and verification are complete",
|
|
25736
25750
|
"code modification (\u2192genesis) or code review (\u2192sentinel)",
|
|
25737
25751
|
"architectural judgment (\u2192nimitz) or release-scope planning decisions (\u2192kirov)",
|
|
25738
|
-
"Fleet Wiki patch approval \u2014
|
|
25752
|
+
"Fleet Wiki patch approval \u2014 host agent retains the wiki_patch_queue approve/reject gate"
|
|
25739
25753
|
],
|
|
25740
25754
|
requestBlocks: [
|
|
25741
25755
|
{
|
|
@@ -25771,18 +25785,18 @@ var CARRIER_METADATA = {
|
|
|
25771
25785
|
],
|
|
25772
25786
|
// ── Tier 2: Composition ──
|
|
25773
25787
|
permissions: [
|
|
25774
|
-
"CRITICAL: Fleet Wiki entries are governed by the Fleet Wiki workspace AGENTS.md doctrine \u2014 propose via wiki_ingest only, and NEVER edit wiki entries or system-managed indexes/logs by hand.
|
|
25788
|
+
"CRITICAL: Fleet Wiki entries are governed by the Fleet Wiki workspace AGENTS.md doctrine \u2014 propose via wiki_ingest only, and NEVER edit wiki entries or system-managed indexes/logs by hand. The host agent holds the wiki_patch_queue approve/reject gate.",
|
|
25775
25789
|
"CRITICAL: Owns codebase markdown \u2014 AGENTS.md, README, CHANGELOG, and inline doc files outside the Fleet Wiki workspace \u2014 and may write them directly. NEVER modify source code logic (report issues instead).",
|
|
25776
|
-
"MUST treat the
|
|
25777
|
-
"Owns expression details (tone, wording, paragraph flow within domain conventions) but MUST NOT silently change structural decisions specified by the
|
|
25790
|
+
"MUST treat the host agent's <doc_type>, <audience>, <scope>, and <change_scope> as binding contracts. NEVER redefine or expand documentation scope autonomously.",
|
|
25791
|
+
"Owns expression details (tone, wording, paragraph flow within domain conventions) but MUST NOT silently change structural decisions specified by the host agent (sections, items, target files).",
|
|
25778
25792
|
"MUST NOT make go/no-go, release timing, or release-scope decisions (escalate to Kirov/Nimitz). May detect and document breaking changes only."
|
|
25779
25793
|
],
|
|
25780
25794
|
outputFormat: `Deliver the documentation artifact directly.
|
|
25781
25795
|
[Codebase Doc] Write the .md/AGENTS.md/README/CHANGELOG file(s) directly via filesystem tools.
|
|
25782
|
-
[Fleet Wiki] Compose the entry body and enqueue via wiki_ingest. Report the patch_id; never edit wiki entries or system-managed files by hand.
|
|
25796
|
+
[Fleet Wiki] Compose the entry body and enqueue via wiki_ingest. Report the patch_id; never edit wiki entries or system-managed files by hand. The host agent approves via wiki_patch_queue.
|
|
25783
25797
|
After delivery, provide a brief completion report.
|
|
25784
25798
|
[Required] always include:
|
|
25785
|
-
**Workflow** \u2014 One of: 'Codebase Doc' or 'Fleet Wiki' (state which workflow this
|
|
25799
|
+
**Workflow** \u2014 One of: 'Codebase Doc' or 'Fleet Wiki' (state which workflow this task used).
|
|
25786
25800
|
**Documents written / Patches enqueued** \u2014 Each file created/modified (Codebase Doc) OR each patch_id enqueued (Fleet Wiki) with target path.
|
|
25787
25801
|
**Cascade .md audit** \u2014 (Codebase Doc only) Each .md inspected: path, status (updated / already consistent / not applicable), 1-line summary if updated.
|
|
25788
25802
|
[If applicable] omit if not relevant:
|
|
@@ -25791,10 +25805,10 @@ After delivery, provide a brief completion report.
|
|
|
25791
25805
|
Keep the completion report concise \u2014 the documentation/patch itself is the primary deliverable.`,
|
|
25792
25806
|
principles: [
|
|
25793
25807
|
CARRIER_JOBS_SELF_CALL_HINT,
|
|
25794
|
-
"Two workflows, one carrier \u2014 never mix the two surfaces. (A) Codebase Doc: direct filesystem edits to .md/AGENTS.md/README/CHANGELOG outside the Fleet Wiki workspace. (B) Fleet Wiki: orient \u2192 consult \u2192 lint \u2192 wiki_ingest to enqueue \u2192
|
|
25795
|
-
"[Fleet Wiki] Read the Fleet Wiki workspace AGENTS.md before the first wiki operation in a
|
|
25808
|
+
"Two workflows, one carrier \u2014 never mix the two surfaces. (A) Codebase Doc: direct filesystem edits to .md/AGENTS.md/README/CHANGELOG outside the Fleet Wiki workspace. (B) Fleet Wiki: orient \u2192 consult \u2192 lint \u2192 wiki_ingest to enqueue \u2192 host agent approves via wiki_patch_queue. Decide the workflow from <doc_type>; if ambiguous, escalate before acting.",
|
|
25809
|
+
"[Fleet Wiki] Read the Fleet Wiki workspace AGENTS.md before the first wiki operation in a task \u2014 it is the authoritative doctrine for boundaries, roles, gates, schema reference, and escalation. The active entry schema may evolve; always consult the workspace doctrine and current schema each task rather than relying on prior memory.",
|
|
25796
25810
|
"[Fleet Wiki] Provide raw evidence (source) alongside every wiki_ingest call \u2014 synthesized entry body must cite raw substance without copying verbatim. The system writes raw, queue, and index automatically.",
|
|
25797
|
-
"[Codebase Doc] Every
|
|
25811
|
+
"[Codebase Doc] Every task must include a cascade .md audit \u2014 identify all .md files within the change scope, verify they reflect current state, and cross-reference parent/child AGENTS.md to prevent doctrinal conflicts.",
|
|
25798
25812
|
"[Codebase Doc] CRITICAL: README.md files must ONLY be updated where they already exist \u2014 NEVER create new README.md files. If a directory lacks a README.md, leave it as-is and note the absence in the audit report.",
|
|
25799
25813
|
"If additional documentation scope seems needed, MUST report it as a follow-up suggestion in the completion report. NEVER silently expand the audit/update scope.",
|
|
25800
25814
|
"Change-impact documentation must be factual and observable \u2014 never recommend whether a change should ship, be reverted, or be delayed."
|
|
@@ -25816,8 +25830,8 @@ var GENESIS_DEFAULTS = {
|
|
|
25816
25830
|
};
|
|
25817
25831
|
var CARRIER_METADATA2 = {
|
|
25818
25832
|
// ── Tier 1: Routing ──
|
|
25819
|
-
title: "
|
|
25820
|
-
summary: "Full-stack implementation workhorse \u2014 builds features, writes production-quality clean code, and maintains structural integrity throughout.
|
|
25833
|
+
title: "Chief Engineer",
|
|
25834
|
+
summary: "Full-stack implementation workhorse \u2014 builds features, writes production-quality clean code, and maintains structural integrity throughout.",
|
|
25821
25835
|
category: "operations",
|
|
25822
25836
|
whenToUse: [
|
|
25823
25837
|
"new features",
|
|
@@ -25844,14 +25858,14 @@ var CARRIER_METADATA2 = {
|
|
|
25844
25858
|
// ── Tier 2: Composition ──
|
|
25845
25859
|
permissions: [
|
|
25846
25860
|
"Full access to the codebase \u2014 read, write, and execute commands.",
|
|
25847
|
-
"Owns implementation details (internal helper structure, code organization, local naming) ONLY within the design boundaries set by the
|
|
25848
|
-
"MUST NOT substitute autonomous design judgment for the
|
|
25861
|
+
"Owns implementation details (internal helper structure, code organization, local naming) ONLY within the design boundaries set by the host agent's instructions.",
|
|
25862
|
+
"MUST NOT substitute autonomous design judgment for the host agent's explicit design decisions \u2014 interface unification vs separation, type/function names, directory structure, public surface shape, and any choice the host agent has specified are BINDING contracts, not suggestions.",
|
|
25849
25863
|
"MUST NOT silently re-plan, expand scope, invent alternative workflows, or shrink the assigned work beyond what the instructions specify.",
|
|
25850
25864
|
"MUST NOT silently absorb Kirov's planning role or Nimitz's architecture arbitration role when those inputs are clearly missing."
|
|
25851
25865
|
],
|
|
25852
25866
|
principles: [
|
|
25853
25867
|
CARRIER_JOBS_SELF_CALL_HINT,
|
|
25854
|
-
"MUST treat the
|
|
25868
|
+
"MUST treat the host agent's <objective>, <scope>, <constraints>, and <references> as binding design contracts. Specific design decisions stated in the instructions MUST be implemented as-instructed, not as 'cleaner' or 'better' substitutions.",
|
|
25855
25869
|
"If an alternative design seems superior, MUST complete the assigned work AS-INSTRUCTED first, then report the alternative ONLY as a follow-up suggestion. NEVER substitute the alternative silently.",
|
|
25856
25870
|
"On ambiguity or apparent conflict in the instructions, MUST report back and request clarification instead of choosing autonomously.",
|
|
25857
25871
|
"Follow planning artifacts when provided \u2014 do not re-plan work that Kirov has already structured unless the input is clearly invalid.",
|
|
@@ -25885,8 +25899,8 @@ var KIROV_DEFAULTS = {
|
|
|
25885
25899
|
};
|
|
25886
25900
|
var CARRIER_METADATA3 = {
|
|
25887
25901
|
// ── Tier 1: Routing ──
|
|
25888
|
-
title: "
|
|
25889
|
-
summary: "Clarifies requirements, closes planning gaps, and writes executable .fleet/plans/*.md
|
|
25902
|
+
title: "Operational Planning",
|
|
25903
|
+
summary: "Clarifies requirements, closes planning gaps, and writes one executable .fleet/plans/*.md plan_file SSoT with explicit parallel lanes, ownership, dependencies, QA gates, acceptance criteria, documentation impacts, and escalation triggers.",
|
|
25890
25904
|
category: "planning",
|
|
25891
25905
|
whenToUse: [
|
|
25892
25906
|
"structured .fleet/plans/*.md plan_file requests, PRD decomposition, or Ohio-executable execution plans",
|
|
@@ -25894,14 +25908,14 @@ var CARRIER_METADATA3 = {
|
|
|
25894
25908
|
"medium/large refactors, migrations, cross-module work, or materially ambiguous requirements where planning must close gaps before execution"
|
|
25895
25909
|
],
|
|
25896
25910
|
whenNotToUse: [
|
|
25897
|
-
"single-Carrier tasks with \u22643 dependent steps and clear acceptance criteria (\
|
|
25911
|
+
"single-Carrier tasks with \u22643 dependent steps and clear acceptance criteria (\u2192host agent plans directly)",
|
|
25898
25912
|
"direct code implementation, single-shot (\u2192genesis) or plan-driven (\u2192ohio)",
|
|
25899
|
-
"final architecture arbitration (\u2192nimitz) or
|
|
25913
|
+
"final architecture arbitration (\u2192nimitz) or dispatches needing reconnaissance first (\u2192vanguard/tempest)"
|
|
25900
25914
|
],
|
|
25901
25915
|
requestBlocks: [
|
|
25902
25916
|
{ tag: "goal", hint: "What the user wants to build, fix, or achieve \u2014 specific feature, PRD, behavior, and any stated constraints.", required: true },
|
|
25903
25917
|
{ tag: "plan_file", hint: "If provided, exact repo-relative .fleet/plans/{name}.md path Kirov must create or update. Do not choose a different filename.", required: false },
|
|
25904
|
-
{ tag: "context", hint: "Relevant codebase context \u2014 files, modules, patterns, prior
|
|
25918
|
+
{ tag: "context", hint: "Relevant codebase context \u2014 files, modules, patterns, prior host-agent direction, or implementation realities the planner should respect.", required: false },
|
|
25905
25919
|
{ tag: "constraints", hint: "Business rules, tech stack requirements, scope boundaries, fixed decisions, or explicit exclusions the plan must respect.", required: false },
|
|
25906
25920
|
{ tag: "intent_type", hint: "If known: Refactoring | Build from Scratch | Mid-sized | Collaborative | Architecture Follow-through | Research-to-Plan.", required: false }
|
|
25907
25921
|
],
|
|
@@ -25909,27 +25923,31 @@ var CARRIER_METADATA3 = {
|
|
|
25909
25923
|
// ── Tier 2: Composition ──
|
|
25910
25924
|
permissions: [
|
|
25911
25925
|
"CRITICAL: Write access strictly limited to .fleet/plans/*.md and .fleet/drafts/*.md. NEVER modify source code, configs, or any non-markdown file.",
|
|
25912
|
-
"MUST honor exact provided .fleet/plans/*.md paths. Success means creating or updating
|
|
25913
|
-
"MUST return unresolved architecture choices, system-design trade-offs, and technical path decisions to the
|
|
25914
|
-
"MUST report Blockers or
|
|
25926
|
+
"MUST honor exact provided .fleet/plans/*.md paths. Keep one plan_file as the execution SSoT: Success means creating or updating that executable plan_file unless the host agent explicitly requests draft-only work. Do not create split plan files for parallel lanes.",
|
|
25927
|
+
"MUST return unresolved architecture choices, system-design trade-offs, and technical path decisions to the host agent for direction instead of silently deciding them.",
|
|
25928
|
+
"MUST report Blockers or Host Direction Needed instead of claiming completion when the plan file cannot be written or the schema cannot be filled."
|
|
25915
25929
|
],
|
|
25916
25930
|
outputFormat: `After completing the plan, provide a structured plan summary.
|
|
25917
25931
|
[Required] always include:
|
|
25918
25932
|
**Plan file** \u2014 Exact generated or updated .fleet/plans/{name}.md path.
|
|
25919
|
-
**Execution
|
|
25933
|
+
**Execution Topology** \u2014 Ordered waves, stable Wave/Lane IDs, parallel markers (e.g., "W1 \u2192 W2 || W3 \u2192 W4"), and critical dependencies.
|
|
25934
|
+
**Dispatch Manifest** \u2014 Each lane's exact write set, start condition, eligible concurrent lanes, integration gate, handoff, and rollback unit.
|
|
25920
25935
|
**Scope: IN** \u2014 What is explicitly included in the plan.
|
|
25921
25936
|
**Scope: OUT** \u2014 What is explicitly excluded.
|
|
25922
25937
|
**Next step** \u2014 Run \`/start-work {name}\` to execute the plan.
|
|
25923
25938
|
[If applicable] omit if not relevant:
|
|
25924
25939
|
**Blockers** \u2014 Why no plan file was written or why the schema cannot be filled.
|
|
25925
|
-
**
|
|
25940
|
+
**Host Direction Needed** \u2014 Architecture, trade-off, or path choices needing confirmation.
|
|
25926
25941
|
Keep the summary concise \u2014 bullets and short lines only. No narrative paragraphs.`,
|
|
25927
25942
|
principles: [
|
|
25928
25943
|
CARRIER_JOBS_SELF_CALL_HINT,
|
|
25929
25944
|
"Clarify only to unlock planning \u2014 ask the minimum questions needed to produce a reliable execution plan.",
|
|
25930
25945
|
"Pre-plan gap analysis is mandatory internal input, never a substitute final output. May launch background explore/librarian sub-agents for context gathering. Use incremental write protocol: Write() skeleton first, then Edit() in 2-4 task batches.",
|
|
25931
|
-
'The .fleet/plans/*.md file MUST contain this exact default Markdown template unless the
|
|
25932
|
-
"
|
|
25946
|
+
'The .fleet/plans/*.md file MUST contain this exact default Markdown template unless the host agent provides a different template: # Objective, # File Ownership, # Execution Topology, - Execution mode: Sequential | Parallel, - Shared mutable resources:, # Waves, ## Wave N \u2014 <name>, ### Lane WN-X \u2014 <name>, - Exact write set:, - Read dependencies:, - Dependency/start condition:, - Eligible concurrent lanes: (use "none" for serialized work), - Integration gate:, - Handoff:, - Rollback unit:, - Implementation summary:, - Verification/static checks:, - Escalation triggers:, # Dispatch Manifest, - Full-plan Ohio invocation (execution_scope omitted or all): allowed sequentially only when Execution mode is Sequential or Execution Topology is absent; for Parallel, dispatch exact Lane IDs only and never combine a full-plan invocation with lane jobs, - Lane WN-X \u2014 <name>: exact write set, read dependencies, dependency/start condition, eligible concurrent lanes, integration gate, handoff, and rollback unit summary for dispatch, # QA Gates, # Acceptance Criteria, # Documentation Updates, # Final Review Loop. Required headings must not be renamed, reordered, or omitted; extra sections allowed only after them. Write headings into the plan_file itself, not just mentioned in the response. For tiny tasks, mark non-applicable fields "Not applicable" rather than deleting them.',
|
|
25947
|
+
"Execution Topology is mandatory for every plan. It MUST declare Execution mode: Sequential | Parallel, shared mutable resources, ordered waves, and stable Wave/Lane IDs; a lane may be marked parallel only when its exact non-overlapping write set and read dependencies prove it is safe to run concurrently.",
|
|
25948
|
+
"Dispatch Manifest is mandatory for every plan. For each parallel lane, declare: stable Wave/Lane ID; exact non-overlapping write set; read dependencies; dependency/start condition; eligible concurrent lanes; integration gate; handoff; and rollback unit. It MUST also state that full-plan Ohio invocation (execution_scope omitted or all) is allowed sequentially only for Sequential or absent Execution Topology; Parallel requires exact Lane IDs, makes full-plan invocation unavailable as an alternative dispatch path, and never combines it with lane jobs. If disjoint lanes cannot be proven safe, mark the work sequential rather than calling it parallel.",
|
|
25949
|
+
"Under each lane's '- Implementation summary:' (or the wave's when a wave declares no lanes), enumerate the concrete implementation steps as a Markdown checkbox task list \u2014 one '- [ ]' line per step, roughly 3-7 per lane; use '- [x]' only for work already completed at planning time. These checkboxes are the machine-readable progress contract consumed by the execution carrier and the Console Plans surface \u2014 do not encode task state in any other notation (no emoji, no status words, no strikethrough).",
|
|
25950
|
+
"Return unresolved architecture and deep trade-off decisions to the host agent for direction.",
|
|
25933
25951
|
"Optimize for direct execution from the resulting plan_file."
|
|
25934
25952
|
]
|
|
25935
25953
|
};
|
|
@@ -25949,8 +25967,8 @@ var NIMITZ_DEFAULTS = {
|
|
|
25949
25967
|
};
|
|
25950
25968
|
var CARRIER_METADATA4 = {
|
|
25951
25969
|
// ── Tier 1: Routing ──
|
|
25952
|
-
title: "
|
|
25953
|
-
summary: "Read-only strategic command \u2014 decides the technical path through doctrinal judgment, architecture decisions, deep analysis, and trade-off adjudication
|
|
25970
|
+
title: "Strategic Command & Judgment",
|
|
25971
|
+
summary: "Read-only strategic command \u2014 decides the technical path through doctrinal judgment, architecture decisions, deep analysis, and trade-off adjudication without entering the implementation path.",
|
|
25954
25972
|
category: "strategy",
|
|
25955
25973
|
whenToUse: [
|
|
25956
25974
|
"architecture and design decisions",
|
|
@@ -25973,7 +25991,7 @@ var CARRIER_METADATA4 = {
|
|
|
25973
25991
|
// ── Tier 2: Composition ──
|
|
25974
25992
|
permissions: [
|
|
25975
25993
|
"CRITICAL: Strictly read-only. NEVER delegate code modification or file editing to this carrier.",
|
|
25976
|
-
"CRITICAL: NEVER
|
|
25994
|
+
"CRITICAL: NEVER dispatch Nimitz without prior reconnaissance \u2014 if recon is needed, dispatch vanguard/tempest FIRST. Hard prerequisite, not a suggestion.",
|
|
25977
25995
|
"Full access to read the codebase and execute read-only commands for analysis.",
|
|
25978
25996
|
"MUST NOT decompose work into task waves, delivery schedules, or implementation checklists \u2014 handoff belongs to Kirov."
|
|
25979
25997
|
],
|
|
@@ -26014,8 +26032,8 @@ var OHIO_DEFAULTS = {
|
|
|
26014
26032
|
};
|
|
26015
26033
|
var CARRIER_METADATA5 = {
|
|
26016
26034
|
// ── Tier 1: Routing ──
|
|
26017
|
-
title: "
|
|
26018
|
-
summary: "Receives a Kirov-authored plan_file and executes it wave-by-wave to completion
|
|
26035
|
+
title: "Multi-Wave Execution",
|
|
26036
|
+
summary: "Receives a Kirov-authored plan_file and executes it wave-by-wave to completion, or one manifest-declared lane when explicitly scoped. Ohio is the sole carrier authorised to consume plan_file inputs.",
|
|
26019
26037
|
category: "planning",
|
|
26020
26038
|
whenToUse: [
|
|
26021
26039
|
"multi-wave builds driven by an explicit plan_file",
|
|
@@ -26024,13 +26042,14 @@ var CARRIER_METADATA5 = {
|
|
|
26024
26042
|
"cross-module coordinated changes following a Kirov plan"
|
|
26025
26043
|
],
|
|
26026
26044
|
whenNotToUse: [
|
|
26027
|
-
"single-file edits or
|
|
26045
|
+
"single-file edits or host-directed single-shot tasks (\u2192genesis)",
|
|
26028
26046
|
"architecture decisions (\u2192nimitz)",
|
|
26029
26047
|
"planning work itself (\u2192kirov)",
|
|
26030
26048
|
"reconnaissance before planning (\u2192vanguard/tempest)"
|
|
26031
26049
|
],
|
|
26032
26050
|
requestBlocks: [
|
|
26033
26051
|
{ tag: "plan_file", hint: "Required repo-relative path to a Markdown plan file under .fleet/plans/*.md only. Ohio reads this file and follows it as the authoritative execution plan.", required: true },
|
|
26052
|
+
{ tag: "execution_scope", hint: "Optional: for legacy plans without Execution Topology or plans marked Execution mode: Sequential, omitted or `all` executes the full plan sequentially. For Execution mode: Parallel, provide one exact Wave/Lane ID declared by the Dispatch Manifest; omitted or `all` is rejected. Never combine a full-plan invocation with scoped-lane Ohio invocation(s).", required: false },
|
|
26034
26053
|
{ tag: "objective", hint: "Optional brief restatement of the overarching goal for context anchoring.", required: false },
|
|
26035
26054
|
{ tag: "scope", hint: "Optional explicit scope boundaries if narrower than the plan_file's full coverage.", required: false },
|
|
26036
26055
|
{ tag: "constraints", hint: "Optional hard constraints, deadlines, or compatibility requirements that override or supplement the plan.", required: false }
|
|
@@ -26040,7 +26059,9 @@ var CARRIER_METADATA5 = {
|
|
|
26040
26059
|
permissions: [
|
|
26041
26060
|
"Full access to the codebase \u2014 read, write, and execute commands.",
|
|
26042
26061
|
"MUST consult plan_file as the authoritative execution contract \u2014 plan steps are not optional or negotiable.",
|
|
26043
|
-
"MUST
|
|
26062
|
+
"MUST read the plan's Execution Topology before resolving execution_scope. For legacy plans without Execution Topology or plans marked Execution mode: Sequential, omitted scope or `all` executes the full plan sequentially. For Execution mode: Parallel, require one exact Dispatch Manifest Wave/Lane ID and reject omitted or `all` scope rather than silently serializing available parallelism. A full-plan invocation (omitted or `all`) MUST NEVER be used alongside scoped-lane Ohio invocation(s).",
|
|
26063
|
+
"When executing a scoped lane, it MUST be exactly one Wave/Lane ID declared by the plan's Dispatch Manifest. A scoped Ohio may change only that lane's declared write set; it MUST NOT edit plan_file, execute unassigned lanes, or guess an ambiguous scope. Before execution, it MUST satisfy the lane's dependency/start condition and required predecessor integration gates; its own QA/integration gate occurs after execution and MUST be satisfied before Ohio reports the lane eligible to release downstream work.",
|
|
26064
|
+
"MUST treat the host agent's <objective>, <scope>, and <constraints> as binding ALONGSIDE the plan_file. Even if a step or constraint seems suboptimal, MUST NOT substitute autonomous design judgment.",
|
|
26044
26065
|
"MUST NOT silently re-plan, skip steps, invent new workflow paths, or expand scope beyond what the plan_file specifies.",
|
|
26045
26066
|
"On genuine blockers (ambiguous step, missing dependency, environmental failure), MUST report back and request re-direction instead of fabricating workarounds."
|
|
26046
26067
|
],
|
|
@@ -26048,13 +26069,17 @@ var CARRIER_METADATA5 = {
|
|
|
26048
26069
|
CARRIER_JOBS_SELF_CALL_HINT,
|
|
26049
26070
|
"Read plan_file as the binding execution contract \u2014 do not deviate, re-plan, or skip steps.",
|
|
26050
26071
|
"Accept only repo-relative Markdown plan paths under .fleet/plans/*.md. If the path is missing, unreadable, outside .fleet/plans/, not repo-relative, or not a .md file, do not guess, do not silently re-plan, and do not invent a replacement workflow \u2014 report the problem back and ask for re-direction.",
|
|
26072
|
+
"Read Execution Topology before resolving execution_scope. For legacy plans without Execution Topology or Execution mode: Sequential, omitted scope or `all` retains full-plan sequential compatibility. For Execution mode: Parallel, require one exact manifest-declared Wave/Lane ID and reject omitted or `all` scope rather than silently serializing available parallelism. Never use a full-plan invocation alongside scoped-lane Ohio invocation(s).",
|
|
26073
|
+
"For a lane scope, change only that lane's declared write set. Never edit plan_file or execute another lane. Before execution, satisfy the lane's dependency/start condition and required predecessor integration gates; after execution, satisfy that lane's own QA/integration gate before reporting it eligible to release downstream work.",
|
|
26051
26074
|
"Execute waves in the declared order; preserve QA checkpoints between waves and do not collapse them.",
|
|
26052
|
-
"
|
|
26075
|
+
"Progress write-back applies to full-plan scope only (execution_scope omitted or `all`): immediately after a wave's QA checkpoint passes, update the plan_file by flipping that wave's completed task checkboxes from '- [ ]' to '- [x]'. This is a state-marker edit only \u2014 never reword, reorder, add, or delete any other plan content while doing it. Flip only steps actually completed; if a completed step has no matching checkbox, leave the text untouched and record the mismatch under Deviations in the completion report. A scoped-lane Ohio never edits plan_file (lane jobs may run concurrently) \u2014 instead it lists the lane's completed task checkboxes in its completion report so the integrator flips them after the lane's integration gate.",
|
|
26076
|
+
"If a wave or constraint should be redesigned, MUST escalate to the host agent via the completion report instead of silently altering the wave's intent.",
|
|
26053
26077
|
"Escalate genuine blockers (ambiguous step, missing dependency, environmental failure) instead of fabricating workarounds.",
|
|
26054
26078
|
"Do not absorb planning, architecture, or QA roles \u2014 if the plan demands a decision Ohio cannot make, escalate to the appropriate carrier (Kirov/Nimitz/Sentinel)."
|
|
26055
26079
|
],
|
|
26056
26080
|
outputFormat: `After completing the assigned wave(s), provide a structured wave-completion report.
|
|
26057
26081
|
[Required] always include:
|
|
26082
|
+
**Execution scope** \u2014 \`all\` or the exact Wave/Lane ID executed from the plan's Dispatch Manifest.
|
|
26058
26083
|
**Wave(s) executed** \u2014 Ordered list of wave/step IDs from the plan_file actually completed.
|
|
26059
26084
|
**Changes** \u2014 Every file created/modified/deleted with a 1-line summary each.
|
|
26060
26085
|
**QA results** \u2014 Outcome of each wave's QA checkpoint (pass/fail with detail).
|
|
@@ -26080,8 +26105,8 @@ var SENTINEL_DEFAULTS = {
|
|
|
26080
26105
|
};
|
|
26081
26106
|
var CARRIER_METADATA6 = {
|
|
26082
26107
|
// ── Tier 1: Routing ──
|
|
26083
|
-
title: "
|
|
26084
|
-
summary: "Bug hunter and security specialist \u2014 code review, defect detection, quality audits, vulnerability hunting, and penetration testing with ruthless precision.
|
|
26108
|
+
title: "QA & Security Lead",
|
|
26109
|
+
summary: "Bug hunter and security specialist \u2014 code review, defect detection, quality audits, vulnerability hunting, and penetration testing with ruthless precision.",
|
|
26085
26110
|
category: "strategy",
|
|
26086
26111
|
whenToUse: [
|
|
26087
26112
|
"code review, bug hunting, quality audits, test execution",
|
|
@@ -26137,8 +26162,8 @@ var TEMPEST_DEFAULTS = {
|
|
|
26137
26162
|
};
|
|
26138
26163
|
var CARRIER_METADATA7 = {
|
|
26139
26164
|
// ── Tier 1: Routing ──
|
|
26140
|
-
title: "
|
|
26141
|
-
summary: "GitHub intelligence \u2014 external repo investigation via API and clone-based deep analysis
|
|
26165
|
+
title: "External Intelligence",
|
|
26166
|
+
summary: "GitHub intelligence \u2014 external repo investigation via API and clone-based deep analysis of upstream repositories and unfamiliar codebases.",
|
|
26142
26167
|
category: "operations",
|
|
26143
26168
|
whenToUse: [
|
|
26144
26169
|
"external GitHub repo investigation (library internals, upstream dependencies)",
|
|
@@ -26193,8 +26218,8 @@ var VANGUARD_DEFAULTS = {
|
|
|
26193
26218
|
};
|
|
26194
26219
|
var CARRIER_METADATA8 = {
|
|
26195
26220
|
// ── Tier 1: Routing ──
|
|
26196
|
-
title: "
|
|
26197
|
-
summary: "Fast reconnaissance \u2014 codebase exploration, symbol tracing, web research
|
|
26221
|
+
title: "Reconnaissance Specialist",
|
|
26222
|
+
summary: "Fast reconnaissance \u2014 codebase exploration, symbol tracing, web research, and external knowledge gathering.",
|
|
26198
26223
|
category: "operations",
|
|
26199
26224
|
whenToUse: [
|
|
26200
26225
|
"codebase reconnaissance \u2014 exploration, multi-file scanning, symbol tracing",
|
|
@@ -32710,7 +32735,7 @@ function resolveDispatchCwd(rawCwd, fallbackCwd) {
|
|
|
32710
32735
|
if (rawCwd === void 0) return { ok: true, cwd: fallbackCwd };
|
|
32711
32736
|
const trimmed = rawCwd.trim();
|
|
32712
32737
|
if (trimmed.length === 0) return { ok: true, cwd: fallbackCwd };
|
|
32713
|
-
if (!
|
|
32738
|
+
if (!path28__default.isAbsolute(trimmed)) {
|
|
32714
32739
|
return {
|
|
32715
32740
|
ok: false,
|
|
32716
32741
|
error: `Invalid cwd "${rawCwd}": must be an absolute path. Provide an absolute directory or omit cwd to use the host session cwd.`
|
|
@@ -32880,7 +32905,7 @@ ${"`"}assumption-audit${"`"} is not a protocol mode and is outside the Mode Gate
|
|
|
32880
32905
|
Never choose ${"`"}protocol-baseline${"`"} or ${"`"}protocol-midline${"`"} when irreversible operations, structural/API changes, multi-module edits, or doctrine/prompt-policy edits are in scope. Choose ${"`"}protocol-redline${"`"} unless coordination across multiple Carriers or parallel ownership boundaries makes ${"`"}protocol-frontline${"`"} the better fit.
|
|
32881
32906
|
|
|
32882
32907
|
## Mode Mapping (examples)
|
|
32883
|
-
Representative
|
|
32908
|
+
Representative user requests mapped to a mode. Match an incoming request to its nearest analog by shape, not exact wording:
|
|
32884
32909
|
|
|
32885
32910
|
| Request shape | Mode | Why |
|
|
32886
32911
|
|---|---|---|
|
|
@@ -32902,7 +32927,7 @@ var CARRIER_OPERATIONS_POLICY = {
|
|
|
32902
32927
|
prompt: String.raw`## Carrier Operations Policy
|
|
32903
32928
|
|
|
32904
32929
|
### Core Principle
|
|
32905
|
-
Delegate execution — retain judgment. Routing, synthesis, and trade-off arbitration stay with the
|
|
32930
|
+
Delegate execution — retain judgment. Routing, synthesis, and trade-off arbitration stay with the host agent.
|
|
32906
32931
|
|
|
32907
32932
|
### Proportionality
|
|
32908
32933
|
Match fleet size to task complexity: single carrier / small fleet / full fleet. Do not expand breadth where a single dispatch suffices.
|
|
@@ -32919,21 +32944,21 @@ Resolve technical trade-offs first; never delegate unresolved decisions to a pla
|
|
|
32919
32944
|
| Synthesis, strategic advice | (no tool) |
|
|
32920
32945
|
|
|
32921
32946
|
### Carrier Invocation
|
|
32922
|
-
Every Carrier lives in <fleet section="roster">. Delegate roster Carrier work through carrier_dispatch. If carrier_dispatch is not exposed in the current tool surface, inspect the Fleet MCP surface first; if it remains unavailable or rejects the requested Carrier, report that limitation to the
|
|
32947
|
+
Every Carrier lives in <fleet section="roster">. Delegate roster Carrier work through carrier_dispatch. If carrier_dispatch is not exposed in the current tool surface, inspect the Fleet MCP surface first; if it remains unavailable or rejects the requested Carrier, report that limitation to the user and await instructions. Never silently substitute a generic agent tool or local execution path for a requested Carrier. carrier_dispatch jobs are fire-and-forget and push completion via [carrier:result].
|
|
32923
32948
|
|
|
32924
32949
|
### Parallel Default
|
|
32925
|
-
When the same phase or step calls multiple
|
|
32950
|
+
When the same phase or step calls multiple Carriers, invoke them in parallel — one tool call per carrier, same response. Sequence only when:
|
|
32926
32951
|
- a later Carrier's work depends on an earlier Carrier's output,
|
|
32927
32952
|
- carriers share a mutable resource (same files, generated artifacts, lock files, singleton test environment), or
|
|
32928
32953
|
- a recon Carrier must complete before a specialist Carrier can be selected.
|
|
32929
32954
|
|
|
32930
32955
|
### Dispatch rules
|
|
32931
|
-
- If the intended Carrier is unavailable: report to
|
|
32956
|
+
- If the intended Carrier is unavailable: report to the user, await instructions. Never silently substitute.
|
|
32932
32957
|
- For carrier tool usage mechanics (request format, brevity, polling, result lookup), the live tool descriptions are authoritative.
|
|
32933
32958
|
|
|
32934
32959
|
### Anti-patterns
|
|
32935
32960
|
- Splitting a parallel launch into sequential calls.
|
|
32936
|
-
-
|
|
32961
|
+
- Dispatching a planning carrier for single-carrier work.
|
|
32937
32962
|
- Falling back to direct work when delegation is appropriate.
|
|
32938
32963
|
- Bypassing carrier_dispatch with a generic agent tool when the task calls for a roster Carrier.`
|
|
32939
32964
|
};
|
|
@@ -32944,7 +32969,7 @@ var COMMAND_INTEGRITY = {
|
|
|
32944
32969
|
name: "Command Integrity",
|
|
32945
32970
|
prompt: String.raw`## Command Integrity Standing Order
|
|
32946
32971
|
|
|
32947
|
-
Governs how the
|
|
32972
|
+
Governs how the host agent receives, questions, and challenges user instructions — upstream of Context Confidence (evidence) and Result Integrity (outcomes). Professionalism is measured by candor and correctness, never by agreement.
|
|
32948
32973
|
|
|
32949
32974
|
### Trigger Mapping
|
|
32950
32975
|
| Trigger | Route |
|
|
@@ -32955,7 +32980,7 @@ Governs how the Admiral receives, questions, and challenges orders from the Admi
|
|
|
32955
32980
|
| Directives conflict | Priority Arbitration |
|
|
32956
32981
|
|
|
32957
32982
|
### Professional Pushback
|
|
32958
|
-
When an
|
|
32983
|
+
When an instruction is technically incorrect or clearly suboptimal, present a reasoned objection with evidence and a concrete alternative before executing. Do not silently execute a flawed instruction, and do not soften a technical objection to please. If the user reaffirms the instruction after hearing the objection, execute it faithfully and record the objection in one line.
|
|
32959
32984
|
|
|
32960
32985
|
### Pre-engagement Clarification
|
|
32961
32986
|
Never assume requirements. When a request is decision-shaped ambiguous — the ambiguity turns on preference, scope, or product intent that evidence cannot settle — apply the ${"`"}assumption-audit${"`"} questioning procedure before loading a protocol mode. Evidence-resolvable ambiguity routes to reconnaissance instead, never to the user.
|
|
@@ -33004,7 +33029,7 @@ If confidence is below the required threshold, do NOT proceed to the gated check
|
|
|
33004
33029
|
2. Triage each gap by the scout-shaped / decision-shaped / escalation-shaped taxonomy defined in ${"`"}assumption-audit${"`"}.
|
|
33005
33030
|
3. Re-evaluate confidence after gap resolution, then re-apply the gate.
|
|
33006
33031
|
|
|
33007
|
-
Gate failure is the gate functioning as designed, not a workflow defect. Repeated failure within the same checkpoint is a signal to escalate to the
|
|
33032
|
+
Gate failure is the gate functioning as designed, not a workflow defect. Repeated failure within the same checkpoint is a signal to escalate to the user, never to lower the threshold.
|
|
33008
33033
|
|
|
33009
33034
|
### Re-evaluation Triggers
|
|
33010
33035
|
|
|
@@ -33036,7 +33061,7 @@ Speculation-trigger handling is routed by the Result Integrity trigger mapping t
|
|
|
33036
33061
|
4. **Repeat** until all speculative elements are either **confirmed with evidence** or explicitly flagged as **unresolvable unknowns**.
|
|
33037
33062
|
|
|
33038
33063
|
### Depth limit
|
|
33039
|
-
Deep Dive verification depth is capped at **2 iterations**. If after 2 rounds of audit + follow-up verification a claim remains unconfirmed, mark it as ${"``"}[Unverified — depth limit reached]${"``"} and report it to the
|
|
33064
|
+
Deep Dive verification depth is capped at **2 iterations**. If after 2 rounds of audit + follow-up verification a claim remains unconfirmed, mark it as ${"``"}[Unverified — depth limit reached]${"``"} and report it to the user. Do not continue iterating — the cost of further verification outweighs the risk of surfaced uncertainty.`
|
|
33040
33065
|
};
|
|
33041
33066
|
|
|
33042
33067
|
// ../../packages/fleet-admiral/src/protocols/standing-orders/mission-anchor.ts
|
|
@@ -33067,7 +33092,7 @@ var RESULT_INTEGRITY = {
|
|
|
33067
33092
|
name: "Result Integrity",
|
|
33068
33093
|
prompt: String.raw`## Result Integrity Standing Order
|
|
33069
33094
|
|
|
33070
|
-
A cross-cutting procedure governing how the
|
|
33095
|
+
A cross-cutting procedure governing how the host agent evaluates Carrier results, handles cross-Carrier feedback loops, and retries failed operations.
|
|
33071
33096
|
|
|
33072
33097
|
### Trigger Mapping
|
|
33073
33098
|
| Trigger | Route |
|
|
@@ -33078,7 +33103,7 @@ A cross-cutting procedure governing how the Admiral evaluates Carrier results, h
|
|
|
33078
33103
|
| Contradiction with verified fact | Re-evaluate Context Confidence. |
|
|
33079
33104
|
|
|
33080
33105
|
### Result Evaluation
|
|
33081
|
-
After receiving any Carrier result, verify before reporting to the
|
|
33106
|
+
After receiving any Carrier result, verify before reporting to the user:
|
|
33082
33107
|
1. **Relevance check** — Does the result address the original request? Flag partial or off-topic responses.
|
|
33083
33108
|
2. **Completeness check** — Are all requested deliverables present (e.g., all files listed, all sections filled)?
|
|
33084
33109
|
3. **Conflict check** — Does the result contradict prior Carrier outputs or known project state?
|
|
@@ -33086,11 +33111,11 @@ After receiving any Carrier result, verify before reporting to the Admiral of th
|
|
|
33086
33111
|
If any check fails, request clarification from the same Carrier with specific feedback before accepting the result.
|
|
33087
33112
|
|
|
33088
33113
|
### Artifact Inspection Gate
|
|
33089
|
-
For any carrier job that mutates the workspace (code, docs, plans, prompts), the three Result Evaluation checks alone do not close the job. Before accepting, the
|
|
33114
|
+
For any carrier job that mutates the workspace (code, docs, plans, prompts), the three Result Evaluation checks alone do not close the job. Before accepting, the host agent MUST inspect the actual artifacts directly — git diff and changed files, retrieved alongside the carrier_jobs response — and judge them against the dispatch intent and the Mission Objective, never against the carrier's narrative alone:
|
|
33090
33115
|
1. Scope — only surfaces within the carrier's declared ownership changed.
|
|
33091
|
-
2. Intent — changes implement the
|
|
33116
|
+
2. Intent — changes implement the host agent's settled decisions, not a plausible reinterpretation.
|
|
33092
33117
|
3. Side effects — no unrelated reverts, history rewrites, or drive-by edits.
|
|
33093
|
-
Report one disposition line: ${"`"}inspection: pass${"`"} | ${"`"}inspection: fixed — <n> deviations corrected by the
|
|
33118
|
+
Report one disposition line: ${"`"}inspection: pass${"`"} | ${"`"}inspection: fixed — <n> deviations corrected by the host agent${"`"} | ${"`"}inspection: rejected — re-dispatched with findings${"`"}. The host agent corrects small deviations directly during integration; systematic deviations route back to the owning carrier. Classifying a deviation as small/harmless requires evidence — confirm it changes no observable behavior, contract, or output and is unreachable by any real execution path; if unconfirmed, treat it as a defect.
|
|
33094
33119
|
Proportionality: full-diff reading for doctrine/prompt/structural changes; stat + targeted sampling for large mechanical changes. Read-only jobs skip this gate — their claims route through Deep Dive instead.
|
|
33095
33120
|
|
|
33096
33121
|
### Multi-agent Filesystem Safety
|
|
@@ -33100,7 +33125,7 @@ Multiple agents may share one branch and filesystem. Re-read files before modify
|
|
|
33100
33125
|
When multiple Carriers contribute to one task: route actionable review findings back to the implementing carrier with explicit fix instructions, re-run the same review on changed code only — never the entire codebase — and run documentation carriers last, only after implementation and verification are complete. Multi-carrier pattern selection lives in ${"`"}protocol-frontline${"`"}.
|
|
33101
33126
|
|
|
33102
33127
|
### Retry Policy
|
|
33103
|
-
On carrier failure (timeout, connection, or runtime error): retry once with the same Carrier and request; on a second failure, report the error details to the
|
|
33128
|
+
On carrier failure (timeout, connection, or runtime error): retry once with the same Carrier and request; on a second failure, report the error details to the user — never retry further or silently substitute another Carrier. Always preserve and report partial output received before a failure.`
|
|
33104
33129
|
};
|
|
33105
33130
|
|
|
33106
33131
|
// ../../packages/fleet-admiral/src/protocols/standing-orders/index.ts
|
|
@@ -33119,7 +33144,7 @@ function getAllStandingOrders() {
|
|
|
33119
33144
|
// ../../packages/fleet-admiral/src/prompts.ts
|
|
33120
33145
|
var FLEET_ROLE_PROMPT = String.raw`
|
|
33121
33146
|
# Role
|
|
33122
|
-
You are the host agent for the Agent Harness Fleet, operating on the user's behalf.
|
|
33147
|
+
You are the host agent for the Agent Harness Fleet, operating on the user's behalf.
|
|
33123
33148
|
|
|
33124
33149
|
# Action Guidelines
|
|
33125
33150
|
- Treat the ${"`"}<fleet section=\"protocol-gate\">${"`"}, the active protocol skill when loaded, and the ${"`"}<fleet section=\"standing-orders\">${"`"} blocks as the binding operational doctrine for every task. The protocol gate, active protocol skill, and all Standing Orders override any default behavior in conflict.
|
|
@@ -33131,17 +33156,23 @@ You are the host agent for the Agent Harness Fleet, operating on the user's beha
|
|
|
33131
33156
|
- Synthesize all user-visible output yourself. Carrier reports, tool outputs, and system reminders are operational inputs to interpret — not conversation turns to reply to, thank, or follow up on.
|
|
33132
33157
|
- When manual control is required, tell the user the manual action in plain language.
|
|
33133
33158
|
`;
|
|
33134
|
-
var
|
|
33159
|
+
var FLEET_METAPHOR_PERSONA_PROMPT = String.raw`
|
|
33135
33160
|
# Persona
|
|
33136
|
-
|
|
33161
|
+
## Active Role Mapping
|
|
33137
33162
|
|
|
33138
|
-
|
|
33139
|
-
|
|
33140
|
-
|
|
33163
|
+
When this persona overlay is present, interpret neutral actor terms in every Fleet instruction through this active role mapping:
|
|
33164
|
+
|
|
33165
|
+
| Neutral actor term | Metaphor role | Required interpretation |
|
|
33166
|
+
|---|---|---|
|
|
33167
|
+
| ${"`"}user${"`"} | **Admiral of the Navy (대원수)** | The human user you serve; the supreme commander above the entire formation. |
|
|
33168
|
+
| ${"`"}host agent${"`"}, ${"`"}you${"`"} | **Admiral (제독)** | Yourself, the agent commanding this Fleet; this title is first-person only. |
|
|
33169
|
+
| ${"`"}Carrier${"`"} | **Captain (함장)** | The acting persona and commander of each registered Carrier. |
|
|
33141
33170
|
|
|
33142
|
-
|
|
33171
|
+
While this persona overlay is present, the two admiral titles are distinct and never collapse onto one — address the user only as the Admiral of the Navy (대원수), and reserve the Admiral (제독) strictly for yourself.
|
|
33172
|
+
|
|
33173
|
+
This is a semantic role mapping for interpretation and conversational wording, not a literal identifier rewrite. Preserve exact functional identifiers, including tool names, ${"`"}carrier_id${"`"} values, skill IDs, XML tags, commands, code symbols, and file paths.
|
|
33143
33174
|
`;
|
|
33144
|
-
var
|
|
33175
|
+
var FLEET_METAPHOR_TONE_PROMPT = String.raw`
|
|
33145
33176
|
# Tone & Manner
|
|
33146
33177
|
This overlay governs HOW you communicate. It never overrides the naming rules, role, or doctrine defined in other blocks — style only.
|
|
33147
33178
|
|
|
@@ -33158,25 +33189,27 @@ Tool results and user messages may include ${"`"}<system-reminder>${"`"} tags ca
|
|
|
33158
33189
|
`;
|
|
33159
33190
|
function createSystemPromptBuilder(deps) {
|
|
33160
33191
|
return {
|
|
33161
|
-
build(
|
|
33162
|
-
return buildSystemPromptFromDeps(deps,
|
|
33192
|
+
build(enableMetaphor) {
|
|
33193
|
+
return buildSystemPromptFromDeps(deps, enableMetaphor);
|
|
33163
33194
|
}
|
|
33164
33195
|
};
|
|
33165
33196
|
}
|
|
33166
|
-
function buildSystemPromptFromDeps(deps,
|
|
33197
|
+
function buildSystemPromptFromDeps(deps, enableMetaphor) {
|
|
33167
33198
|
const parts = [];
|
|
33168
33199
|
parts.push(`<fleet section="preamble">
|
|
33169
33200
|
${FLEET_PREAMBLE.trim()}
|
|
33170
33201
|
</fleet>`);
|
|
33171
|
-
|
|
33172
|
-
|
|
33202
|
+
if (enableMetaphor) {
|
|
33203
|
+
parts.push(`<fleet section="persona">
|
|
33204
|
+
${FLEET_METAPHOR_PERSONA_PROMPT.trim()}
|
|
33173
33205
|
</fleet>`);
|
|
33206
|
+
}
|
|
33174
33207
|
parts.push(`<fleet section="role">
|
|
33175
33208
|
${FLEET_ROLE_PROMPT.trim()}
|
|
33176
33209
|
</fleet>`);
|
|
33177
|
-
if (
|
|
33210
|
+
if (enableMetaphor) {
|
|
33178
33211
|
parts.push(`<fleet section="tone">
|
|
33179
|
-
${
|
|
33212
|
+
${FLEET_METAPHOR_TONE_PROMPT.trim()}
|
|
33180
33213
|
</fleet>`);
|
|
33181
33214
|
}
|
|
33182
33215
|
const carrierRuntime = deps.carrierRuntime;
|
|
@@ -33420,7 +33453,7 @@ function requireSystemPromptFile(context) {
|
|
|
33420
33453
|
var TOML_BASIC_STRING_ESCAPE_PATTERN = /[\u0000-\u001f"\\\u007f]/g;
|
|
33421
33454
|
var TOML_MULTILINE_CONTROL_PATTERN = new RegExp("[\\u0000-\\u0008\\u000b-\\u001f\\u007f]", "g");
|
|
33422
33455
|
var TOML_MULTILINE_QUOTE_RUN_PATTERN = /"+/g;
|
|
33423
|
-
function
|
|
33456
|
+
function escapeTomlBasicString(value) {
|
|
33424
33457
|
return value.replace(TOML_BASIC_STRING_ESCAPE_PATTERN, (char) => {
|
|
33425
33458
|
switch (char) {
|
|
33426
33459
|
case "\b":
|
|
@@ -33493,9 +33526,9 @@ function buildCodexNativeArgs(context) {
|
|
|
33493
33526
|
const bearerHeader = `Bearer ${server.bearerToken}`;
|
|
33494
33527
|
args.push(
|
|
33495
33528
|
"-c",
|
|
33496
|
-
`${prefix}.url="${
|
|
33529
|
+
`${prefix}.url="${escapeTomlBasicString(server.endpointUrl)}"`,
|
|
33497
33530
|
"-c",
|
|
33498
|
-
`${prefix}.http_headers={"Authorization" = "${
|
|
33531
|
+
`${prefix}.http_headers={"Authorization" = "${escapeTomlBasicString(bearerHeader)}"}`,
|
|
33499
33532
|
"-c",
|
|
33500
33533
|
`${prefix}.tool_timeout_sec=${CODEX_TOOL_TIMEOUT_SEC}`
|
|
33501
33534
|
);
|
|
@@ -33530,67 +33563,12 @@ function buildResumeArgs4(resumeSessionId) {
|
|
|
33530
33563
|
|
|
33531
33564
|
// ../../packages/fleet-admiral/src/agent-cli/assets.generated.ts
|
|
33532
33565
|
var EMBEDDED_AGENT_CLI_SKILL_ASSETS = [
|
|
33533
|
-
{ relativePath: "assumption-audit/SKILL.md", content: "---\nname: assumption-audit\ndescription: Resolve decision-shaped blocking gaps one at a time \u2014 Context Confidence gate failures during an active protocol, or pre-engagement requirements ambiguity routed by the Command Integrity Standing Order.\n---\n\nUse this auxiliary skill only when a decision-shaped blocking gap has been found: either the active protocol or Context Confidence re-entry path surfaced it, or the Command Integrity Standing Order routed a pre-engagement requirements ambiguity here before a protocol mode loads. This skill is not a protocol mode, does not replace the active protocol, and cannot declare the planning boundary passed by itself.\n\nFor each unresolved blocking gap, triage the gap before questioning:\n\n- **Scout-shaped**: the answer should come from direct file reads, focused reconnaissance, carrier scouting, or another verifiable evidence source. Send the workflow back to that evidence-gathering path instead of asking the user to decide.\n- **Decision-shaped**: the answer depends on preference, scope, risk appetite, product intent, or authority that evidence alone cannot settle. Ask exactly one question for this gap.\n- **Escalation-shaped**: the answer requires authority beyond the current operator, changes the mission boundary, repeatedly fails to resolve, or would weaken the active protocol's required gate. Escalate to the
|
|
33534
|
-
{ relativePath: "carrier-contracts/SKILL.md", content:
|
|
33535
|
-
|
|
33536
|
-
|
|
33537
|
-
|
|
33538
|
-
|
|
33539
|
-
# Carrier Request-Block Contracts
|
|
33540
|
-
|
|
33541
|
-
This skill owns only the request composition contract. Carrier selection and routing stay in \`<fleet section="roster">\`; dispatch mechanics (label, brevity, polling, result lookup) stay in the live \`carrier_dispatch\` tool description. Missing required blocks cause hard-error rejection that echoes the violated carrier's contract.
|
|
33542
|
-
|
|
33543
|
-
All carriers accept an optional \`<prior_jobs>\` block: Prior finalized carrier job IDs for context lookup. Fetch with carrier_jobs(action:"result", format:"full", job_id:...); use format:"summary" if archive content has expired.
|
|
33544
|
-
|
|
33545
|
-
## Contracts by carrier
|
|
33546
|
-
- **nimitz** (Nimitz \xB7 Captain \xB7 Strategic Command & Judgment) \u2014 wrap request content in these blocks (? = optional):
|
|
33547
|
-
- <context> required: Background situation, current state, and relevant history.
|
|
33548
|
-
- <problem> required: The specific question, decision point, or challenge to analyze.
|
|
33549
|
-
- <constraints?> optional: Hard constraints, deadlines, compatibility requirements.
|
|
33550
|
-
- <artifacts?> optional: Relevant code snippets, file paths, error logs to examine.
|
|
33551
|
-
- **kirov** (Kirov \xB7 Captain \xB7 Operational Planning Bridge) \u2014 wrap request content in these blocks (? = optional):
|
|
33552
|
-
- <goal> required: What the user wants to build, fix, or achieve \u2014 specific feature, PRD, behavior, and any stated constraints.
|
|
33553
|
-
- <plan_file?> optional: If provided, exact repo-relative .fleet/plans/{name}.md path Kirov must create or update. Do not choose a different filename.
|
|
33554
|
-
- <context?> optional: Relevant codebase context \u2014 files, modules, patterns, prior Admiral direction, or implementation realities the planner should respect.
|
|
33555
|
-
- <constraints?> optional: Business rules, tech stack requirements, scope boundaries, fixed decisions, or explicit exclusions the plan must respect.
|
|
33556
|
-
- <intent_type?> optional: If known: Refactoring | Build from Scratch | Mid-sized | Collaborative | Architecture Follow-through | Research-to-Plan.
|
|
33557
|
-
- **genesis** (Genesis \xB7 Captain \xB7 Chief Engineer) \u2014 wrap request content in these blocks (? = optional):
|
|
33558
|
-
- <objective> required: What needs to be built or achieved. Be specific about the desired end state.
|
|
33559
|
-
- <scope> required: Which modules, directories, or subsystems are in play.
|
|
33560
|
-
- <constraints?> optional: Hard technical constraints, compatibility requirements, or non-negotiables.
|
|
33561
|
-
- <references?> optional: Prior Nimitz recommendations, Kirov plans, existing patterns to follow, or design decisions already made.
|
|
33562
|
-
- **ohio** (Ohio \xB7 Captain \xB7 Multi-Wave Strike Execution) \u2014 wrap request content in these blocks (? = optional):
|
|
33563
|
-
- <plan_file> required: Required repo-relative path to a Markdown plan file under .fleet/plans/*.md only. Ohio reads this file and follows it as the authoritative execution plan.
|
|
33564
|
-
- <objective?> optional: Optional brief restatement of the overarching goal for context anchoring.
|
|
33565
|
-
- <scope?> optional: Optional explicit scope boundaries if narrower than the plan_file's full coverage.
|
|
33566
|
-
- <constraints?> optional: Optional hard constraints, deadlines, or compatibility requirements that override or supplement the plan.
|
|
33567
|
-
- **sentinel** (Sentinel \xB7 Captain \xB7 The Inquisitor / QA & Security Lead) \u2014 wrap request content in these blocks (? = optional):
|
|
33568
|
-
- <target> required: Which files, modules, PRs, endpoints, or recent changes to inspect.
|
|
33569
|
-
- <concern?> optional: Specific suspicion, symptom, or area of worry to focus on.
|
|
33570
|
-
- <context?> optional: Background on what the code does and expected behavior.
|
|
33571
|
-
- <attack_surface?> optional: Known entry points, user-controlled inputs, or external interfaces (security mode).
|
|
33572
|
-
- <threat_model?> optional: Assumed attacker capability \u2014 unauth user, compromised dep, insider (security mode).
|
|
33573
|
-
- <fix_mode?> optional: 'report' (default) for findings only, or 'fix' to apply corrections.
|
|
33574
|
-
- **vanguard** (Vanguard \xB7 Captain \xB7 Scout Specialist) \u2014 wrap request content in these blocks (? = optional):
|
|
33575
|
-
- <objective> required: What intelligence is needed \u2014 question to answer or target to locate.
|
|
33576
|
-
- <search_space?> optional: Directories, files, URLs, or domains to focus the search on.
|
|
33577
|
-
- <hints?> optional: Known symbols, keywords, file patterns, or prior findings to narrow the scan.
|
|
33578
|
-
- <depth?> optional: 'quick' for surface scan, 'thorough' for exhaustive. Default: 'medium'.
|
|
33579
|
-
- **tempest** (Tempest \xB7 Captain \xB7 External Intelligence Strike) \u2014 wrap request content in these blocks (? = optional):
|
|
33580
|
-
- <target_repo> required: Repository to investigate (owner/repo format or full URL).
|
|
33581
|
-
- <objective> required: What intelligence is needed \u2014 feature, pattern, API usage, or implementation detail.
|
|
33582
|
-
- <focus_areas?> optional: Specific directories, files, symbols, or code patterns to prioritize.
|
|
33583
|
-
- <constraints?> optional: Time constraints, specific branches/tags, or areas to exclude.
|
|
33584
|
-
- **chronicle** (Chronicle \xB7 Captain \xB7 Chief Knowledge Officer) \u2014 wrap request content in these blocks (? = optional):
|
|
33585
|
-
- <target> required: [Codebase Doc] which code, module, PR, feature, or release artifact to document. [Fleet Wiki] which feature area or wiki entry slug.
|
|
33586
|
-
- <doc_type> required: [Codebase Doc] README, API spec, PR summary, release notes, changelog, AGENTS.md, '.md-audit', change-impact summary, breaking-change report, migration guide. [Fleet Wiki] 'wiki-create' (new entry) or 'wiki-update' (existing entry revision).
|
|
33587
|
-
- <audience> required: developers, end-users, API consumers, operators, or contributors.
|
|
33588
|
-
- <scope?> optional: [Codebase Doc] include/exclude; for changelogs/change-impact/audits: commit range, PR, diff, feature slice, deployment scope. [Fleet Wiki] feature_area, target wiki id (for update), tags.
|
|
33589
|
-
` },
|
|
33590
|
-
{ relativePath: "protocol-baseline/SKILL.md", content: "---\nname: protocol-baseline\ndescription: Use the compact Fleet protocol mode for simple, reversible, single-surface work.\n---\n\n# Fleet Protocol: Baseline\n\nUse this mode only for simple, reversible, single-surface operational work.\n\nAt any point during the work, if a Downward Guard trigger appears, stop and re-classify.\n\n## Checkpoints\n\nNone. Selecting baseline implies Mission Anchor Compact Mode.\n\n## Reporting Cadence\n\nAs you move through this protocol, report progress to the Admiral of the Navy in order.\n\n1. Brief in one line how the Workflow will proceed. \u2192 report `brief: <\u2026>`\n2. State that execution is beginning and run the Workflow. \u2192 report `status: executing`\n\n## General Quarters\n\nConfirm each readiness check below before the Workflow. Work through them in order and report each as you confirm it, then proceed to the Objective anchor. These checks prepare the work; they do not gate entry.\n\n- [ ] **Common** \u2014 objective stated (Mission Anchor), mode-fit holds (Mode Gate), Standing Orders binding. \u2192 report `common: ready`\n- [ ] **Single surface** \u2014 the exact file, command, or fact is identified. \u2192 report `surface: <x>`\n- [ ] **Reversibility** \u2014 the change is trivially reversible. \u2192 report `reversible: yes`\n\n## Workflow\n\n1. Objective statement: state the Mission Anchor objective in one line.\n2. Exact fact/file verification: verify the exact file, command, or fact needed for the request.\n3. Execution: make the smallest reversible change or run the exact requested command.\n4. Result verification: check the touched surface or command result.\n5. One-line report: report what changed, verification, and any skipped escalation trigger.\n" },
|
|
33591
|
-
{ relativePath: "protocol-frontline/SKILL.md", content: "---\nname: protocol-frontline\ndescription: Use the coordinated Fleet protocol mode for multi-carrier or parallel ownership work.\n---\n\n# Fleet Protocol: Frontline\n\nUse this mode when operational work requires multiple Carriers, independent parallel workstreams, cross-carrier review loops, or file ownership coordination. If the work is high risk but single-owner, use `protocol-redline` instead.\n\n## Checkpoints\n\nDecomposition, Dispatch, Integration, Verification.\n\n## Reporting Cadence\n\nAs you move through this protocol, report progress to the Admiral of the Navy in order \u2014 each step on its own line with its report token.\n\n1. Brief how the Workflow will proceed \u2014 name (a) the Workflow steps that will run, (b) each carrier's file or responsibility ownership, and (c) the dispatch wave sequencing. \u2192 report `brief: <\u2026>`\n2. State that execution is beginning and run the Workflow. \u2192 report `status: executing`\n\n## General Quarters\n\nConfirm each readiness check below before the Workflow. Work through them in order and report each as you confirm it, then proceed to reconnaissance and decomposition. These checks prepare the work; they do not gate entry.\n\n- [ ] **Common** \u2014 objective stated (Mission Anchor), mode-fit holds (Mode Gate), Standing Orders binding. \u2192 report `common: ready`\n- [ ] **Impact radius** \u2014 flag public-surface or API impact, irreversibility, and any security-sensitive surface. \u2192 report `impact: <\u2026>`\n- [ ] **Rollback** \u2014 identify a rollback-safe checkpoint and any Admiral of the Navy approval point before execution begins. \u2192 report `rollback: <\u2026>`\n- [ ] **Carrier availability** \u2014 confirm the intended carriers are actually exposed and available this session. \u2192 report `carriers: <\u2026>`\n- [ ] **Ownership** \u2014 pre-sketch each carrier's file or responsibility boundary. \u2192 report `ownership: <\u2026>`\n- [ ] **Shared resources** \u2014 flag shared mutable resources (same files, lock files, or a singleton test environment). \u2192 report `shared: <\u2026|none>`\n- [ ] **Dependencies** \u2014 pre-classify parallel versus sequential work before decomposition and dispatch. \u2192 report `dependencies: <parallel|sequenced: \u2026>`\n\n## Workflow\n\n1. Reconnaissance and decomposition: audit known facts, identify gaps, map affected surfaces, and split work into independently verifiable missions.\n2. Ownership graph: assign each Carrier a clear file or responsibility boundary, note dependencies, and identify shared mutable resources.\n3. Structured planning boundary: `Apply the Context Confidence Standing Order \u2014 entry requires complete`. Resolve all blocking and confirmatory gaps before dispatch planning.\n4. Parallel dispatch: use Carrier Operations Policy to launch independent Carrier work in parallel; sequence only for explicit dependencies or shared resources.\n5. Integration: re-read files before editing or accepting Carrier output, reconcile overlaps, and preserve unrelated user or Carrier changes.\n6. Cross-carrier review loop: route implementation outputs to review Carriers, send actionable findings back to owners, and re-review changed surfaces.\n7. Verification: run integrated tests and apply Deep Dive to speculative or conflicting Carrier claims.\n8. Documentation and completion report: update directly affected docs and report executed waves, Carrier ownership, QA, unresolved risks, and final Result Integrity checks.\n\n## Cross-Carrier Feedback Patterns\n\nWhen composing waves and review loops, select the structured feedback pattern that fits the task:\n\n| Pattern | Flow | When |\n|---------|------|------|\n| **Build \u2192 Review** | implementation carrier \u2192 review carrier \u2192 findings back to implementation carrier \u2192 re-review | Standard implementation cycle |\n| **Analyze \u2192 Execute** | implementation or refactoring carrier \u2192 review carrier verifies | Refactoring workflow |\n| **Decide \u2192 Plan \u2192 Execute** | judgment carrier \u2192 planning carrier \u2192 execution carrier | Complex features |\n| **Research \u2192 Act** | reconnaissance carrier \u2192 appropriate follow-up carrier from the active roster | Unknown scope tasks |\n" },
|
|
33592
|
-
{ relativePath: "protocol-midline/SKILL.md", content: "---\nname: protocol-midline\ndescription: Use the normal Fleet protocol mode for bounded operational work without downward-guard triggers.\n---\n\n# Fleet Protocol: Midline\n\nUse this mode for ordinary bounded operational work.\n\nAt any point during the work, if a Downward Guard trigger appears, stop and re-classify.\n\n## Checkpoints\n\nReconnaissance, Plan, Execution, Verification.\n\n## Reporting Cadence\n\nAs you move through this protocol, report progress to the Admiral of the Navy in order \u2014 each step on its own line with its report token.\n\n1. Brief how the Workflow will proceed \u2014 name (a) the Workflow steps that will run, (b) the target surfaces, and (c) the verification command. \u2192 report `brief: <\u2026>`\n2. State that execution is beginning and run the Workflow. \u2192 report `status: executing`\n\n## General Quarters\n\nConfirm each readiness check below before the Workflow. Work through them in order and report each as you confirm it, then proceed to focused reconnaissance. These checks prepare the work; they do not gate entry.\n\n- [ ] **Common** \u2014 objective stated (Mission Anchor), mode-fit holds (Mode Gate), Standing Orders binding. \u2192 report `common: ready`\n- [ ] **Target surfaces** \u2014 provisionally name the minimal modules or files reconnaissance will touch; confirm or revise in the brief after reconnaissance. \u2192 report `surfaces: <\u2026>`\n- [ ] **Verification** \u2014 provisionally pre-load the test, build, or check command that will prove the work done; confirm or revise in the brief after reconnaissance. \u2192 report `verify: <cmd>`\n- [ ] **Carrier** \u2014 declare whether a carrier sortie is needed. \u2192 report `carrier: <none|\u2026>`\n\n## Workflow\n\n1. Focused reconnaissance: audit known facts, identify blocking and confirmatory gaps, and inspect the minimal relevant surfaces.\n2. Planning boundary: `Apply the Context Confidence Standing Order \u2014 entry requires sufficient`. Resolve all blocking gaps before planning.\n3. Inline plan: state objective, targets, execution steps, and done criteria.\n4. Execution: implement the plan in narrow batches, using Carrier Operations Policy when delegation is appropriate.\n5. Verification and review: run targeted checks, apply Deep Dive to speculative results, and fix actionable issues.\n6. Documentation and final report: update directly affected docs only when behavior or operator guidance changed, then summarize changes and QA.\n" },
|
|
33593
|
-
{ relativePath: "protocol-redline/SKILL.md", content: "---\nname: protocol-redline\ndescription: Use the risk-controlled Fleet protocol mode for irreversible, structural, multi-module, or prompt-policy work.\n---\n\n# Fleet Protocol: Redline\n\nUse this mode when any Downward Guard trigger defined in the Protocol Gate is in scope, for security-sensitive work, or for any operational request needing explicit risk controls. Escalate to `protocol-frontline` when multiple Carriers or parallel ownership boundaries are required.\n\n## Checkpoints\n\nReconnaissance, Risk review, Plan, Execution, Verification.\n\n## Reporting Cadence\n\nAs you move through this protocol, report progress to the Admiral of the Navy in order \u2014 each step on its own line with its report token.\n\n1. Brief how the Workflow will proceed \u2014 name (a) the Workflow steps that will run, (b) file ownership and the rollback-safe checkpoint, and (c) the risk controls in force. \u2192 report `brief: <\u2026>`\n2. State that execution is beginning and run the Workflow. \u2192 report `status: executing`\n\n## General Quarters\n\nConfirm each readiness check below before the Workflow. Work through them in order and report each as you confirm it, then proceed to full reconnaissance. These checks prepare the work; they do not gate entry.\n\n- [ ] **Common** \u2014 objective stated (Mission Anchor), mode-fit holds (Mode Gate), Standing Orders binding. \u2192 report `common: ready`\n- [ ] **Doctrine** \u2014 enumerate the applicable AGENTS.md files to load for the affected scope. \u2192 report `doctrine: <\u2026>`\n- [ ] **Impact radius** \u2014 flag public-surface or API impact, irreversibility, and any security-sensitive surface. \u2192 report `impact: <\u2026>`\n- [ ] **Rollback** \u2014 identify a rollback-safe checkpoint and any Admiral of the Navy approval point before execution begins. \u2192 report `rollback: <\u2026>`\n- [ ] **Escalation** \u2014 if multiple carriers or parallel ownership boundaries are required, re-classify under frontline. \u2192 report `escalation: clear`\n\n## Workflow\n\n1. Full reconnaissance: audit known facts, enumerate blocking and confirmatory gaps, read applicable AGENTS.md files, map affected code, tests, docs, and boundaries.\n2. Architecture and risk review: identify public-surface impact, dependency constraints, rollback risk, security risk, and Admiral of the Navy approval requirements.\n3. Structured planning boundary: `Apply the Context Confidence Standing Order \u2014 entry requires complete`. Do not plan with unresolved blocking or confirmatory gaps.\n4. Risk-controlled plan: define file ownership, small execution batches, verification commands, rollback-safe checkpoints, and any approval point.\n5. Small-batch execution: edit narrowly, re-read before modifying shared files, and pause on unexpected diffs or scope expansion.\n6. Refactor gate: refactor only touched code when duplication, complexity, or convention drift appears, only with Admiral of the Navy approval or when pre-declared in the brief.\n7. Correctness and security review (may run as a single combined review dispatch): review changed behavior and risk controls; apply Deep Dive to speculative findings and repeat after fixes.\n8. Documentation and completion report: update directly affected operator docs and report changes, QA, risk controls, and residual uncertainty.\n" }
|
|
33566
|
+
{ relativePath: "assumption-audit/SKILL.md", content: "---\nname: assumption-audit\ndescription: Resolve decision-shaped blocking gaps one at a time \u2014 Context Confidence gate failures during an active protocol, or pre-engagement requirements ambiguity routed by the Command Integrity Standing Order.\n---\n\nUse this auxiliary skill only when a decision-shaped blocking gap has been found: either the active protocol or Context Confidence re-entry path surfaced it, or the Command Integrity Standing Order routed a pre-engagement requirements ambiguity here before a protocol mode loads. This skill is not a protocol mode, does not replace the active protocol, and cannot declare the planning boundary passed by itself.\n\nFor each unresolved blocking gap, triage the gap before questioning:\n\n- **Scout-shaped**: the answer should come from direct file reads, focused reconnaissance, carrier scouting, or another verifiable evidence source. Send the workflow back to that evidence-gathering path instead of asking the user to decide.\n- **Decision-shaped**: the answer depends on preference, scope, risk appetite, product intent, or authority that evidence alone cannot settle. Ask exactly one question for this gap.\n- **Escalation-shaped**: the answer requires authority beyond the current operator, changes the mission boundary, repeatedly fails to resolve, or would weaken the active protocol's required gate. Escalate to the user.\n\nWhen a gap is decision-shaped, ask one question at a time. Present your recommended answer first, then give one or two concrete alternatives when useful. Walk decision dependencies one branch at a time until the current gap is resolved; do not bundle unrelated gaps into the same question.\n\nAfter the gap is answered, report the resolved decision in one short line and return control to the caller: the active protocol or Context Confidence Standing Order on re-entry, or the Protocol Gate when invoked pre-engagement. An active workflow must re-evaluate confidence and re-apply the required planning boundary gate before planning proceeds.\n" },
|
|
33567
|
+
{ relativePath: "carrier-contracts/SKILL.md", content: "---\nname: carrier-contracts\ndescription: Per-carrier request-block contracts for composing carrier_dispatch requests. Load before the first dispatch of the session; skip reloading if already in context.\n---\n\n# Carrier Request-Block Contracts\n\nThis skill owns only the request composition contract. Carrier selection and routing stay in `<fleet section=\"roster\">`; dispatch mechanics (label, brevity, polling, result lookup) stay in the live `carrier_dispatch` tool description. Missing required blocks cause hard-error rejection that echoes the violated carrier's contract.\n\nAll carriers accept an optional `<prior_jobs>` block: Prior finalized carrier job IDs for context lookup. Fetch with carrier_jobs(action:\"result\", format:\"full\", job_id:...); use format:\"summary\" if archive content has expired.\n\n## Contracts by carrier\n- **nimitz** (Nimitz \xB7 Strategic Command & Judgment) \u2014 wrap request content in these blocks (? = optional):\n - <context> required: Background situation, current state, and relevant history.\n - <problem> required: The specific question, decision point, or challenge to analyze.\n - <constraints?> optional: Hard constraints, deadlines, compatibility requirements.\n - <artifacts?> optional: Relevant code snippets, file paths, error logs to examine.\n- **kirov** (Kirov \xB7 Operational Planning) \u2014 wrap request content in these blocks (? = optional):\n - <goal> required: What the user wants to build, fix, or achieve \u2014 specific feature, PRD, behavior, and any stated constraints.\n - <plan_file?> optional: If provided, exact repo-relative .fleet/plans/{name}.md path Kirov must create or update. Do not choose a different filename.\n - <context?> optional: Relevant codebase context \u2014 files, modules, patterns, prior host-agent direction, or implementation realities the planner should respect.\n - <constraints?> optional: Business rules, tech stack requirements, scope boundaries, fixed decisions, or explicit exclusions the plan must respect.\n - <intent_type?> optional: If known: Refactoring | Build from Scratch | Mid-sized | Collaborative | Architecture Follow-through | Research-to-Plan.\n- **genesis** (Genesis \xB7 Chief Engineer) \u2014 wrap request content in these blocks (? = optional):\n - <objective> required: What needs to be built or achieved. Be specific about the desired end state.\n - <scope> required: Which modules, directories, or subsystems are in play.\n - <constraints?> optional: Hard technical constraints, compatibility requirements, or non-negotiables.\n - <references?> optional: Prior Nimitz recommendations, Kirov plans, existing patterns to follow, or design decisions already made.\n- **ohio** (Ohio \xB7 Multi-Wave Execution) \u2014 wrap request content in these blocks (? = optional):\n - <plan_file> required: Required repo-relative path to a Markdown plan file under .fleet/plans/*.md only. Ohio reads this file and follows it as the authoritative execution plan.\n - <execution_scope?> optional: Optional: for legacy plans without Execution Topology or plans marked Execution mode: Sequential, omitted or `all` executes the full plan sequentially. For Execution mode: Parallel, provide one exact Wave/Lane ID declared by the Dispatch Manifest; omitted or `all` is rejected. Never combine a full-plan invocation with scoped-lane Ohio invocation(s).\n - <objective?> optional: Optional brief restatement of the overarching goal for context anchoring.\n - <scope?> optional: Optional explicit scope boundaries if narrower than the plan_file's full coverage.\n - <constraints?> optional: Optional hard constraints, deadlines, or compatibility requirements that override or supplement the plan.\n- **sentinel** (Sentinel \xB7 QA & Security Lead) \u2014 wrap request content in these blocks (? = optional):\n - <target> required: Which files, modules, PRs, endpoints, or recent changes to inspect.\n - <concern?> optional: Specific suspicion, symptom, or area of worry to focus on.\n - <context?> optional: Background on what the code does and expected behavior.\n - <attack_surface?> optional: Known entry points, user-controlled inputs, or external interfaces (security mode).\n - <threat_model?> optional: Assumed attacker capability \u2014 unauth user, compromised dep, insider (security mode).\n - <fix_mode?> optional: 'report' (default) for findings only, or 'fix' to apply corrections.\n- **vanguard** (Vanguard \xB7 Reconnaissance Specialist) \u2014 wrap request content in these blocks (? = optional):\n - <objective> required: What intelligence is needed \u2014 question to answer or target to locate.\n - <search_space?> optional: Directories, files, URLs, or domains to focus the search on.\n - <hints?> optional: Known symbols, keywords, file patterns, or prior findings to narrow the scan.\n - <depth?> optional: 'quick' for surface scan, 'thorough' for exhaustive. Default: 'medium'.\n- **tempest** (Tempest \xB7 External Intelligence) \u2014 wrap request content in these blocks (? = optional):\n - <target_repo> required: Repository to investigate (owner/repo format or full URL).\n - <objective> required: What intelligence is needed \u2014 feature, pattern, API usage, or implementation detail.\n - <focus_areas?> optional: Specific directories, files, symbols, or code patterns to prioritize.\n - <constraints?> optional: Time constraints, specific branches/tags, or areas to exclude.\n- **chronicle** (Chronicle \xB7 Chief Knowledge Officer) \u2014 wrap request content in these blocks (? = optional):\n - <target> required: [Codebase Doc] which code, module, PR, feature, or release artifact to document. [Fleet Wiki] which feature area or wiki entry slug.\n - <doc_type> required: [Codebase Doc] README, API spec, PR summary, release notes, changelog, AGENTS.md, '.md-audit', change-impact summary, breaking-change report, migration guide. [Fleet Wiki] 'wiki-create' (new entry) or 'wiki-update' (existing entry revision).\n - <audience> required: developers, end-users, API consumers, operators, or contributors.\n - <scope?> optional: [Codebase Doc] include/exclude; for changelogs/change-impact/audits: commit range, PR, diff, feature slice, deployment scope. [Fleet Wiki] feature_area, target wiki id (for update), tags.\n" },
|
|
33568
|
+
{ relativePath: "protocol-baseline/SKILL.md", content: "---\nname: protocol-baseline\ndescription: Use the compact Fleet protocol mode for simple, reversible, single-surface work.\n---\n\n# Fleet Protocol: Baseline\n\nUse this mode only for simple, reversible, single-surface operational work.\n\nAt any point during the work, if a Downward Guard trigger appears, stop and re-classify.\n\n## Checkpoints\n\nNone. Selecting baseline implies Mission Anchor Compact Mode.\n\n## Reporting Cadence\n\nAs you move through this protocol, report progress to the user in order.\n\n1. Brief in one line how the Workflow will proceed. \u2192 report `brief: <\u2026>`\n2. State that execution is beginning and run the Workflow. \u2192 report `status: executing`\n\n## General Quarters\n\nConfirm each readiness check below before the Workflow. Work through them in order and report each as you confirm it, then proceed to the Objective anchor. These checks prepare the work; they do not gate entry.\n\n- [ ] **Common** \u2014 objective stated (Mission Anchor), mode-fit holds (Mode Gate), Standing Orders binding. \u2192 report `common: ready`\n- [ ] **Single surface** \u2014 the exact file, command, or fact is identified. \u2192 report `surface: <x>`\n- [ ] **Reversibility** \u2014 the change is trivially reversible. \u2192 report `reversible: yes`\n\n## Workflow\n\n1. Objective statement: state the Mission Anchor objective in one line.\n2. Exact fact/file verification: verify the exact file, command, or fact needed for the request.\n3. Execution: make the smallest reversible change or run the exact requested command.\n4. Result verification: check the touched surface or command result.\n5. One-line report: report what changed, verification, and any skipped escalation trigger.\n" },
|
|
33569
|
+
{ relativePath: "protocol-frontline/SKILL.md", content: "---\nname: protocol-frontline\ndescription: Use the coordinated Fleet protocol mode for multi-carrier or parallel ownership work.\n---\n\n# Fleet Protocol: Frontline\n\nUse this mode when operational work requires multiple Carriers, independent parallel workstreams, cross-carrier review loops, or file ownership coordination. If the work is high risk but single-owner, use `protocol-redline` instead.\n\n## Checkpoints\n\nDecomposition, Dispatch, Integration, Verification.\n\n## Reporting Cadence\n\nAs you move through this protocol, report progress to the user in order \u2014 each step on its own line with its report token.\n\n1. Brief how the Workflow will proceed \u2014 name (a) the Workflow steps that will run, (b) each carrier's file or responsibility ownership, and (c) the dispatch wave sequencing. \u2192 report `brief: <\u2026>`\n2. State that execution is beginning and run the Workflow. \u2192 report `status: executing`\n\n## General Quarters\n\nConfirm each readiness check below before the Workflow. Work through them in order and report each as you confirm it, then proceed to reconnaissance and decomposition. These checks prepare the work; they do not gate entry.\n\n- [ ] **Common** \u2014 objective stated (Mission Anchor), mode-fit holds (Mode Gate), Standing Orders binding. \u2192 report `common: ready`\n- [ ] **Impact radius** \u2014 flag public-surface or API impact, irreversibility, and any security-sensitive surface. \u2192 report `impact: <\u2026>`\n- [ ] **Rollback** \u2014 identify a rollback-safe checkpoint and any user approval point before execution begins. \u2192 report `rollback: <\u2026>`\n- [ ] **Carrier availability** \u2014 confirm the intended carriers are actually exposed and available this session. \u2192 report `carriers: <\u2026>`\n- [ ] **Ownership** \u2014 pre-sketch each carrier's file or responsibility boundary. \u2192 report `ownership: <\u2026>`\n- [ ] **Shared resources** \u2014 flag shared mutable resources (same files, lock files, or a singleton test environment). \u2192 report `shared: <\u2026|none>`\n- [ ] **Dependencies** \u2014 pre-classify parallel versus sequential work before decomposition and dispatch. \u2192 report `dependencies: <parallel|sequenced: \u2026>`\n\n## Workflow\n\n1. Reconnaissance and decomposition: audit known facts, identify gaps, map affected surfaces, and split work into independently verifiable missions.\n2. Ownership graph: assign each Carrier a clear file or responsibility boundary, note dependencies, and identify shared mutable resources.\n3. Structured planning boundary: `Apply the Context Confidence Standing Order \u2014 entry requires complete`. Resolve all blocking and confirmatory gaps before dispatch planning.\n4. Parallel dispatch: use Carrier Operations Policy to launch independent Carrier work in parallel; sequence only for explicit dependencies or shared resources.\n5. Integration: re-read files before editing or accepting Carrier output, reconcile overlaps, and preserve unrelated user or Carrier changes.\n6. Cross-carrier review loop: route implementation outputs to review Carriers, send actionable findings back to owners, and re-review changed surfaces.\n7. Verification: run integrated tests and apply Deep Dive to speculative or conflicting Carrier claims.\n8. Documentation and completion report: update directly affected docs and report executed waves, Carrier ownership, QA, unresolved risks, and final Result Integrity checks.\n\n## Cross-Carrier Feedback Patterns\n\nWhen composing waves and review loops, select the structured feedback pattern that fits the task:\n\n| Pattern | Flow | When |\n|---------|------|------|\n| **Build \u2192 Review** | implementation carrier \u2192 review carrier \u2192 findings back to implementation carrier \u2192 re-review | Standard implementation cycle |\n| **Analyze \u2192 Execute** | implementation or refactoring carrier \u2192 review carrier verifies | Refactoring workflow |\n| **Decide \u2192 Plan \u2192 Execute** | judgment carrier \u2192 planning carrier \u2192 execution carrier | Complex features |\n| **Research \u2192 Act** | reconnaissance carrier \u2192 appropriate follow-up carrier from the active roster | Unknown scope tasks |\n" },
|
|
33570
|
+
{ relativePath: "protocol-midline/SKILL.md", content: "---\nname: protocol-midline\ndescription: Use the normal Fleet protocol mode for bounded operational work without downward-guard triggers.\n---\n\n# Fleet Protocol: Midline\n\nUse this mode for ordinary bounded operational work.\n\nAt any point during the work, if a Downward Guard trigger appears, stop and re-classify.\n\n## Checkpoints\n\nReconnaissance, Plan, Execution, Verification.\n\n## Reporting Cadence\n\nAs you move through this protocol, report progress to the user in order \u2014 each step on its own line with its report token.\n\n1. Brief how the Workflow will proceed \u2014 name (a) the Workflow steps that will run, (b) the target surfaces, and (c) the verification command. \u2192 report `brief: <\u2026>`\n2. State that execution is beginning and run the Workflow. \u2192 report `status: executing`\n\n## General Quarters\n\nConfirm each readiness check below before the Workflow. Work through them in order and report each as you confirm it, then proceed to focused reconnaissance. These checks prepare the work; they do not gate entry.\n\n- [ ] **Common** \u2014 objective stated (Mission Anchor), mode-fit holds (Mode Gate), Standing Orders binding. \u2192 report `common: ready`\n- [ ] **Target surfaces** \u2014 provisionally name the minimal modules or files reconnaissance will touch; confirm or revise in the brief after reconnaissance. \u2192 report `surfaces: <\u2026>`\n- [ ] **Verification** \u2014 provisionally pre-load the test, build, or check command that will prove the work done; confirm or revise in the brief after reconnaissance. \u2192 report `verify: <cmd>`\n- [ ] **Carrier** \u2014 declare whether a carrier dispatch is needed. \u2192 report `carrier: <none|\u2026>`\n\n## Workflow\n\n1. Focused reconnaissance: audit known facts, identify blocking and confirmatory gaps, and inspect the minimal relevant surfaces.\n2. Planning boundary: `Apply the Context Confidence Standing Order \u2014 entry requires sufficient`. Resolve all blocking gaps before planning.\n3. Inline plan: state objective, targets, execution steps, and done criteria.\n4. Execution: implement the plan in narrow batches, using Carrier Operations Policy when delegation is appropriate.\n5. Verification and review: run targeted checks, apply Deep Dive to speculative results, and fix actionable issues.\n6. Documentation and final report: update directly affected docs only when behavior or operator guidance changed, then summarize changes and QA.\n" },
|
|
33571
|
+
{ relativePath: "protocol-redline/SKILL.md", content: "---\nname: protocol-redline\ndescription: Use the risk-controlled Fleet protocol mode for irreversible, structural, multi-module, or prompt-policy work.\n---\n\n# Fleet Protocol: Redline\n\nUse this mode when any Downward Guard trigger defined in the Protocol Gate is in scope, for security-sensitive work, or for any operational request needing explicit risk controls. Escalate to `protocol-frontline` when multiple Carriers or parallel ownership boundaries are required.\n\n## Checkpoints\n\nReconnaissance, Risk review, Plan, Execution, Verification.\n\n## Reporting Cadence\n\nAs you move through this protocol, report progress to the user in order \u2014 each step on its own line with its report token.\n\n1. Brief how the Workflow will proceed \u2014 name (a) the Workflow steps that will run, (b) file ownership and the rollback-safe checkpoint, and (c) the risk controls in force. \u2192 report `brief: <\u2026>`\n2. State that execution is beginning and run the Workflow. \u2192 report `status: executing`\n\n## General Quarters\n\nConfirm each readiness check below before the Workflow. Work through them in order and report each as you confirm it, then proceed to full reconnaissance. These checks prepare the work; they do not gate entry.\n\n- [ ] **Common** \u2014 objective stated (Mission Anchor), mode-fit holds (Mode Gate), Standing Orders binding. \u2192 report `common: ready`\n- [ ] **Doctrine** \u2014 enumerate the applicable AGENTS.md files to load for the affected scope. \u2192 report `doctrine: <\u2026>`\n- [ ] **Impact radius** \u2014 flag public-surface or API impact, irreversibility, and any security-sensitive surface. \u2192 report `impact: <\u2026>`\n- [ ] **Rollback** \u2014 identify a rollback-safe checkpoint and any user approval point before execution begins. \u2192 report `rollback: <\u2026>`\n- [ ] **Escalation** \u2014 if multiple carriers or parallel ownership boundaries are required, re-classify under frontline. \u2192 report `escalation: clear`\n\n## Workflow\n\n1. Full reconnaissance: audit known facts, enumerate blocking and confirmatory gaps, read applicable AGENTS.md files, map affected code, tests, docs, and boundaries.\n2. Architecture and risk review: identify public-surface impact, dependency constraints, rollback risk, security risk, and user approval requirements.\n3. Structured planning boundary: `Apply the Context Confidence Standing Order \u2014 entry requires complete`. Do not plan with unresolved blocking or confirmatory gaps.\n4. Risk-controlled plan: define file ownership, small execution batches, verification commands, rollback-safe checkpoints, and any approval point.\n5. Small-batch execution: edit narrowly, re-read before modifying shared files, and pause on unexpected diffs or scope expansion.\n6. Refactor gate: refactor only touched code when duplication, complexity, or convention drift appears, only with user approval or when pre-declared in the brief.\n7. Correctness and security review (may run as a single combined review dispatch): review changed behavior and risk controls; apply Deep Dive to speculative findings and repeat after fixes.\n8. Documentation and completion report: update directly affected operator docs and report changes, QA, risk controls, and residual uncertainty.\n" }
|
|
33594
33572
|
];
|
|
33595
33573
|
var DIR_MODE = 448;
|
|
33596
33574
|
var FILE_MODE = 384;
|
|
@@ -33606,7 +33584,7 @@ function writePrivateJson(filePath, value, rootBase) {
|
|
|
33606
33584
|
function writePrivateFile(filePath, content, rootBase) {
|
|
33607
33585
|
const resolvedBase = ensureRootBase(rootBase);
|
|
33608
33586
|
ensurePathWithinRoot(resolvedBase, filePath);
|
|
33609
|
-
ensureDirectorySegments(resolvedBase,
|
|
33587
|
+
ensureDirectorySegments(resolvedBase, path28__default.dirname(filePath));
|
|
33610
33588
|
writeFileNoFollow(filePath, content);
|
|
33611
33589
|
chmodBestEffort(filePath, FILE_MODE);
|
|
33612
33590
|
}
|
|
@@ -33653,20 +33631,20 @@ function writeFileNoFollow(filePath, content) {
|
|
|
33653
33631
|
}
|
|
33654
33632
|
}
|
|
33655
33633
|
function ensureRootBase(rootBase) {
|
|
33656
|
-
const resolvedBase =
|
|
33657
|
-
const anchor = findExistingDirectoryAnchor(
|
|
33634
|
+
const resolvedBase = path28__default.resolve(rootBase);
|
|
33635
|
+
const anchor = findExistingDirectoryAnchor(path28__default.dirname(resolvedBase));
|
|
33658
33636
|
ensureDirectorySegments(anchor, resolvedBase);
|
|
33659
33637
|
assertDirectorySafe(resolvedBase, "Plugin root base");
|
|
33660
33638
|
return resolvedBase;
|
|
33661
33639
|
}
|
|
33662
33640
|
function assertRootBaseSafe(rootBase) {
|
|
33663
|
-
const resolvedBase =
|
|
33664
|
-
assertExistingSegmentsSafe(findExistingDirectoryAnchor(
|
|
33641
|
+
const resolvedBase = path28__default.resolve(rootBase);
|
|
33642
|
+
assertExistingSegmentsSafe(findExistingDirectoryAnchor(path28__default.dirname(resolvedBase)), resolvedBase);
|
|
33665
33643
|
assertDirectorySafe(resolvedBase, "Plugin root base");
|
|
33666
33644
|
return resolvedBase;
|
|
33667
33645
|
}
|
|
33668
33646
|
function findExistingDirectoryAnchor(targetPath) {
|
|
33669
|
-
const resolvedTarget =
|
|
33647
|
+
const resolvedTarget = path28__default.resolve(targetPath);
|
|
33670
33648
|
let current = resolvedTarget;
|
|
33671
33649
|
while (true) {
|
|
33672
33650
|
try {
|
|
@@ -33674,7 +33652,7 @@ function findExistingDirectoryAnchor(targetPath) {
|
|
|
33674
33652
|
return current;
|
|
33675
33653
|
} catch (error51) {
|
|
33676
33654
|
if (error51 instanceof Error && "code" in error51 && error51.code === "ENOENT") {
|
|
33677
|
-
const parent =
|
|
33655
|
+
const parent = path28__default.dirname(current);
|
|
33678
33656
|
if (parent === current) throw error51;
|
|
33679
33657
|
current = parent;
|
|
33680
33658
|
continue;
|
|
@@ -33693,17 +33671,17 @@ function assertDirectorySafe(dirPath, label) {
|
|
|
33693
33671
|
}
|
|
33694
33672
|
}
|
|
33695
33673
|
function ensurePathWithinRoot(resolvedBase, candidatePath) {
|
|
33696
|
-
const resolvedCandidate =
|
|
33697
|
-
const relative =
|
|
33698
|
-
if (relative === "" || !relative.startsWith("..") && !
|
|
33674
|
+
const resolvedCandidate = path28__default.resolve(candidatePath);
|
|
33675
|
+
const relative = path28__default.relative(resolvedBase, resolvedCandidate);
|
|
33676
|
+
if (relative === "" || !relative.startsWith("..") && !path28__default.isAbsolute(relative)) return;
|
|
33699
33677
|
throw new Error(`Plugin path escapes root base: ${candidatePath}`);
|
|
33700
33678
|
}
|
|
33701
33679
|
function ensureDirectorySegments(resolvedBase, dirPath) {
|
|
33702
|
-
const target =
|
|
33703
|
-
const relative =
|
|
33680
|
+
const target = path28__default.resolve(dirPath);
|
|
33681
|
+
const relative = path28__default.relative(resolvedBase, target);
|
|
33704
33682
|
let current = resolvedBase;
|
|
33705
|
-
for (const segment of relative.split(
|
|
33706
|
-
current =
|
|
33683
|
+
for (const segment of relative.split(path28__default.sep).filter(Boolean)) {
|
|
33684
|
+
current = path28__default.join(current, segment);
|
|
33707
33685
|
try {
|
|
33708
33686
|
const stat3 = lstatSync(current);
|
|
33709
33687
|
if (stat3.isSymbolicLink()) {
|
|
@@ -33724,11 +33702,11 @@ function ensureDirectorySegments(resolvedBase, dirPath) {
|
|
|
33724
33702
|
}
|
|
33725
33703
|
}
|
|
33726
33704
|
function assertExistingSegmentsSafe(resolvedBase, targetPath) {
|
|
33727
|
-
const target =
|
|
33728
|
-
const relative =
|
|
33705
|
+
const target = path28__default.resolve(targetPath);
|
|
33706
|
+
const relative = path28__default.relative(resolvedBase, target);
|
|
33729
33707
|
let current = resolvedBase;
|
|
33730
|
-
for (const segment of relative.split(
|
|
33731
|
-
current =
|
|
33708
|
+
for (const segment of relative.split(path28__default.sep).filter(Boolean)) {
|
|
33709
|
+
current = path28__default.join(current, segment);
|
|
33732
33710
|
const stat3 = lstatSync(current);
|
|
33733
33711
|
if (stat3.isSymbolicLink()) {
|
|
33734
33712
|
throw new Error(`Plugin path segment is a symlink: ${current}`);
|
|
@@ -33740,27 +33718,22 @@ function assertExistingSegmentsSafe(resolvedBase, targetPath) {
|
|
|
33740
33718
|
}
|
|
33741
33719
|
}
|
|
33742
33720
|
function assertExistingParentSegmentsSafe(resolvedBase, targetPath) {
|
|
33743
|
-
assertExistingSegmentsSafe(resolvedBase,
|
|
33721
|
+
assertExistingSegmentsSafe(resolvedBase, path28__default.dirname(targetPath));
|
|
33744
33722
|
}
|
|
33745
33723
|
function assertSegmentRealpathWithinRoot(resolvedBase, segmentPath) {
|
|
33746
33724
|
const baseRealpath = realpathSync(resolvedBase);
|
|
33747
33725
|
const segmentRealpath = realpathSync(segmentPath);
|
|
33748
|
-
const relative =
|
|
33749
|
-
if (relative === "" || !relative.startsWith("..") && !
|
|
33726
|
+
const relative = path28__default.relative(baseRealpath, segmentRealpath);
|
|
33727
|
+
if (relative === "" || !relative.startsWith("..") && !path28__default.isAbsolute(relative)) return;
|
|
33750
33728
|
throw new Error(`Plugin path segment escapes root base: ${segmentPath}`);
|
|
33751
33729
|
}
|
|
33752
33730
|
|
|
33753
|
-
// ../../packages/fleet-admiral/src/agent-cli/
|
|
33754
|
-
var
|
|
33755
|
-
var
|
|
33756
|
-
|
|
33757
|
-
globs:
|
|
33758
|
-
alwaysApply: true
|
|
33759
|
-
---
|
|
33760
|
-
`;
|
|
33761
|
-
var CURSOR_DOCTRINE_RULE_PREAMBLE = `# Fleet Runtime Doctrine for Cursor Agent
|
|
33731
|
+
// ../../packages/fleet-admiral/src/agent-cli/doctrine-hook.ts
|
|
33732
|
+
var DOCTRINE_FILE_NAME = "doctrine.md";
|
|
33733
|
+
var DOCTRINE_HOOK_SCRIPT_NAME = "inject-doctrine.mjs";
|
|
33734
|
+
var CURSOR_DOCTRINE_PREAMBLE = `# Fleet Runtime Doctrine for Cursor Agent
|
|
33762
33735
|
|
|
33763
|
-
You are running as Cursor Agent inside Fleet.
|
|
33736
|
+
You are running as Cursor Agent inside Fleet. This context was injected through a Fleet sessionStart hook. Treat the embedded Fleet system prompt below as your active Fleet runtime doctrine.
|
|
33764
33737
|
|
|
33765
33738
|
Priority and interpretation:
|
|
33766
33739
|
|
|
@@ -33774,13 +33747,39 @@ Priority and interpretation:
|
|
|
33774
33747
|
|
|
33775
33748
|
## Embedded Fleet System Prompt
|
|
33776
33749
|
|
|
33777
|
-
The following block is the Fleet system prompt content adapted for Cursor
|
|
33750
|
+
The following block is the Fleet system prompt content adapted for Cursor hook injection. It is intentionally embedded verbatim after this wrapper.
|
|
33778
33751
|
|
|
33779
33752
|
<fleet-system-prompt>
|
|
33780
33753
|
`;
|
|
33781
|
-
var
|
|
33754
|
+
var CURSOR_DOCTRINE_FOOTER = `
|
|
33782
33755
|
</fleet-system-prompt>
|
|
33783
33756
|
`;
|
|
33757
|
+
var INJECT_DOCTRINE_HOOK_SCRIPT = `import fs from "node:fs";
|
|
33758
|
+
import path from "node:path";
|
|
33759
|
+
import { fileURLToPath } from "node:url";
|
|
33760
|
+
|
|
33761
|
+
const pluginRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
33762
|
+
const doctrine = fs.readFileSync(path.join(pluginRoot, "${DOCTRINE_FILE_NAME}"), "utf8");
|
|
33763
|
+
process.stdout.write(JSON.stringify({ additional_context: doctrine }));
|
|
33764
|
+
`;
|
|
33765
|
+
function formatCursorDoctrine(doctrine) {
|
|
33766
|
+
return `${CURSOR_DOCTRINE_PREAMBLE}${doctrine}${CURSOR_DOCTRINE_FOOTER}`;
|
|
33767
|
+
}
|
|
33768
|
+
function renderCursorDoctrineHookAssets(pluginRoot, doctrine, hookCommandRoot = pluginRoot) {
|
|
33769
|
+
writePrivateFile(
|
|
33770
|
+
path28__default.join(pluginRoot, DOCTRINE_FILE_NAME),
|
|
33771
|
+
formatCursorDoctrine(doctrine),
|
|
33772
|
+
pluginRoot
|
|
33773
|
+
);
|
|
33774
|
+
const scriptPath = path28__default.join(hookCommandRoot, "hooks", DOCTRINE_HOOK_SCRIPT_NAME);
|
|
33775
|
+
writePrivateFile(path28__default.join(pluginRoot, "hooks", DOCTRINE_HOOK_SCRIPT_NAME), INJECT_DOCTRINE_HOOK_SCRIPT, pluginRoot);
|
|
33776
|
+
return {
|
|
33777
|
+
command: process.execPath,
|
|
33778
|
+
args: [scriptPath]
|
|
33779
|
+
};
|
|
33780
|
+
}
|
|
33781
|
+
|
|
33782
|
+
// ../../packages/fleet-admiral/src/agent-cli/plugin/fleet.ts
|
|
33784
33783
|
var assetBundle = {
|
|
33785
33784
|
description: "Fleet carrier delegation and wiki evidence plugin",
|
|
33786
33785
|
directoryName: "fleet",
|
|
@@ -33791,11 +33790,16 @@ var assetBundle = {
|
|
|
33791
33790
|
};
|
|
33792
33791
|
function renderAssetPluginRoot(pluginRoot, bundle, options) {
|
|
33793
33792
|
renderEmbeddedSkillAssets(pluginRoot);
|
|
33793
|
+
const doctrineHookExec = options.cliId === "cursor" && options.doctrine !== void 0 ? renderCursorDoctrineHookAssets(
|
|
33794
|
+
pluginRoot,
|
|
33795
|
+
options.doctrine,
|
|
33796
|
+
options.installedPluginRoot ?? pluginRoot
|
|
33797
|
+
) : void 0;
|
|
33794
33798
|
if (options.cliId === "claude") {
|
|
33795
|
-
writePrivateJson(
|
|
33799
|
+
writePrivateJson(path28__default.join(pluginRoot, "hooks", "hooks.json"), claudeHooks(options), pluginRoot);
|
|
33796
33800
|
}
|
|
33797
33801
|
if (options.cliId === "cursor") {
|
|
33798
|
-
renderCursorPluginRoot(pluginRoot, options);
|
|
33802
|
+
renderCursorPluginRoot(pluginRoot, options, doctrineHookExec);
|
|
33799
33803
|
}
|
|
33800
33804
|
}
|
|
33801
33805
|
function claudeHooks(options) {
|
|
@@ -33836,25 +33840,15 @@ function claudeCommandHook(hookExec) {
|
|
|
33836
33840
|
type: "command"
|
|
33837
33841
|
};
|
|
33838
33842
|
}
|
|
33839
|
-
function renderCursorPluginRoot(pluginRoot, options) {
|
|
33840
|
-
if (options.doctrine !== void 0) {
|
|
33841
|
-
renderCursorDoctrineRule(pluginRoot, options.doctrine);
|
|
33842
|
-
}
|
|
33843
|
+
function renderCursorPluginRoot(pluginRoot, options, doctrineHookExec) {
|
|
33843
33844
|
if ((options.mcpServers ?? []).length > 0) {
|
|
33844
|
-
writePrivateJson(
|
|
33845
|
+
writePrivateJson(path28__default.join(pluginRoot, "mcp.json"), cursorMcpConfig(options.mcpServers ?? []), pluginRoot);
|
|
33845
33846
|
}
|
|
33846
|
-
const hooks = cursorHooks(options);
|
|
33847
|
+
const hooks = cursorHooks(options, doctrineHookExec);
|
|
33847
33848
|
if (hooks !== void 0) {
|
|
33848
|
-
writePrivateJson(
|
|
33849
|
+
writePrivateJson(path28__default.join(pluginRoot, "hooks", "hooks.json"), hooks, pluginRoot);
|
|
33849
33850
|
}
|
|
33850
33851
|
}
|
|
33851
|
-
function renderCursorDoctrineRule(pluginRoot, doctrine) {
|
|
33852
|
-
writePrivateFile(
|
|
33853
|
-
path27__default.join(pluginRoot, "rules", CURSOR_DOCTRINE_RULE_FILE),
|
|
33854
|
-
`${CURSOR_DOCTRINE_RULE_FRONTMATTER}${CURSOR_DOCTRINE_RULE_PREAMBLE}${doctrine}${CURSOR_DOCTRINE_RULE_FOOTER}`,
|
|
33855
|
-
pluginRoot
|
|
33856
|
-
);
|
|
33857
|
-
}
|
|
33858
33852
|
function cursorMcpConfig(servers) {
|
|
33859
33853
|
return {
|
|
33860
33854
|
mcpServers: Object.fromEntries(
|
|
@@ -33868,8 +33862,8 @@ function cursorMcpConfig(servers) {
|
|
|
33868
33862
|
)
|
|
33869
33863
|
};
|
|
33870
33864
|
}
|
|
33871
|
-
function cursorHooks(options) {
|
|
33872
|
-
const sessionStartExecs = [options.captureSessionHookExec].filter((exec) => exec !== void 0);
|
|
33865
|
+
function cursorHooks(options, doctrineHookExec) {
|
|
33866
|
+
const sessionStartExecs = [doctrineHookExec, options.captureSessionHookExec].filter((exec) => exec !== void 0);
|
|
33873
33867
|
const beforeSubmitPromptExecs = [options.turnStartHookExec, options.autoNameHookExec].filter((exec) => exec !== void 0);
|
|
33874
33868
|
const stopExecs = [options.turnEndHookExec].filter((exec) => exec !== void 0);
|
|
33875
33869
|
if (sessionStartExecs.length === 0 && beforeSubmitPromptExecs.length === 0 && stopExecs.length === 0) return void 0;
|
|
@@ -33892,7 +33886,7 @@ function cursorCommandHook(hookExec, extraArgs = []) {
|
|
|
33892
33886
|
}
|
|
33893
33887
|
function renderEmbeddedSkillAssets(pluginRoot) {
|
|
33894
33888
|
for (const asset of EMBEDDED_AGENT_CLI_SKILL_ASSETS) {
|
|
33895
|
-
writePrivateFile(
|
|
33889
|
+
writePrivateFile(path28__default.join(pluginRoot, "skills", asset.relativePath), asset.content, pluginRoot);
|
|
33896
33890
|
}
|
|
33897
33891
|
}
|
|
33898
33892
|
var CONFIG_FILE_NAME = "config.toml";
|
|
@@ -33907,7 +33901,7 @@ function neutralizeCodexFleetPluginConfig(options) {
|
|
|
33907
33901
|
mutateCodexConfigWithRetry(options, 0);
|
|
33908
33902
|
}
|
|
33909
33903
|
function mutateCodexConfigWithRetry(options, attempt) {
|
|
33910
|
-
const configPath =
|
|
33904
|
+
const configPath = path28__default.join(options.codexHome, CONFIG_FILE_NAME);
|
|
33911
33905
|
const targetPath = resolveRealConfigPath(configPath);
|
|
33912
33906
|
const snapshot = readConfigSnapshot(targetPath);
|
|
33913
33907
|
const nextContent = patchCodexConfig(snapshot.content, options);
|
|
@@ -33928,7 +33922,7 @@ function resolveRealConfigPath(configPath) {
|
|
|
33928
33922
|
} catch (error51) {
|
|
33929
33923
|
if (!isNodeError(error51, "ENOENT")) throw error51;
|
|
33930
33924
|
try {
|
|
33931
|
-
return
|
|
33925
|
+
return path28__default.join(realpathSync(path28__default.dirname(configPath)), path28__default.basename(configPath));
|
|
33932
33926
|
} catch (dirError) {
|
|
33933
33927
|
if (isNodeError(dirError, "ENOENT")) return configPath;
|
|
33934
33928
|
throw dirError;
|
|
@@ -33965,9 +33959,9 @@ function readConfigSnapshot(configPath) {
|
|
|
33965
33959
|
}
|
|
33966
33960
|
}
|
|
33967
33961
|
function writeConfigIfUnchanged(configPath, snapshot, content) {
|
|
33968
|
-
mkdirSync(
|
|
33962
|
+
mkdirSync(path28__default.dirname(configPath), { recursive: true, mode: 448 });
|
|
33969
33963
|
assertConfigUnchanged(configPath, snapshot);
|
|
33970
|
-
const tempPath =
|
|
33964
|
+
const tempPath = path28__default.join(path28__default.dirname(configPath), `.${path28__default.basename(configPath)}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`);
|
|
33971
33965
|
let fd;
|
|
33972
33966
|
try {
|
|
33973
33967
|
fd = openSync(tempPath, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, CONFIG_FILE_MODE);
|
|
@@ -34215,7 +34209,7 @@ function ensureCodexPluginRegisteredOrThrow(registration, command, runCommand) {
|
|
|
34215
34209
|
pluginKey
|
|
34216
34210
|
});
|
|
34217
34211
|
writePrivateFile(registration.hashPath, `${registration.contentHash}
|
|
34218
|
-
`,
|
|
34212
|
+
`, path28__default.dirname(registration.hashPath));
|
|
34219
34213
|
}
|
|
34220
34214
|
function assertCommandSucceeded(label, result) {
|
|
34221
34215
|
if (result.status === 0) return;
|
|
@@ -34223,7 +34217,7 @@ function assertCommandSucceeded(label, result) {
|
|
|
34223
34217
|
throw new Error(`${label} failed${detail.length > 0 ? `: ${detail}` : ""}`);
|
|
34224
34218
|
}
|
|
34225
34219
|
function resolveCodexHome(env) {
|
|
34226
|
-
return env.CODEX_HOME ??
|
|
34220
|
+
return env.CODEX_HOME ?? path28__default.join(env.HOME ?? os3__default.homedir(), ".codex");
|
|
34227
34221
|
}
|
|
34228
34222
|
function findMarketplaceEntries(result, marketplaceName) {
|
|
34229
34223
|
return parseMarketplaceEntries(result).filter((entry) => entry.name === marketplaceName);
|
|
@@ -34239,7 +34233,7 @@ function parseMarketplaceEntries(result) {
|
|
|
34239
34233
|
return entries;
|
|
34240
34234
|
}
|
|
34241
34235
|
function normalizeMarketplaceRoot(rootPath, cwd) {
|
|
34242
|
-
const resolved =
|
|
34236
|
+
const resolved = path28__default.resolve(cwd, rootPath);
|
|
34243
34237
|
try {
|
|
34244
34238
|
return realpathSync(resolved);
|
|
34245
34239
|
} catch (error51) {
|
|
@@ -34263,7 +34257,7 @@ function readHash(hashPath) {
|
|
|
34263
34257
|
}
|
|
34264
34258
|
function removeFlatMarketplaceResidue(projectMarketplaceRoot) {
|
|
34265
34259
|
for (const entry of FLAT_MARKETPLACE_FS_RESIDUE_ENTRIES) {
|
|
34266
|
-
removePrivatePath(
|
|
34260
|
+
removePrivatePath(path28__default.join(projectMarketplaceRoot, entry), projectMarketplaceRoot);
|
|
34267
34261
|
}
|
|
34268
34262
|
}
|
|
34269
34263
|
|
|
@@ -34323,7 +34317,7 @@ async function createAgentCliPlugin(options) {
|
|
|
34323
34317
|
cleanup,
|
|
34324
34318
|
codexRegistrations: options.cliId === "codex" ? renderableBundles.map(({ bundle, target }, index) => ({
|
|
34325
34319
|
contentHash: contentHashes.get(target.root),
|
|
34326
|
-
hashPath:
|
|
34320
|
+
hashPath: path28__default.join(target.root, bundle.hashFileName),
|
|
34327
34321
|
marketplaceDir: target.root,
|
|
34328
34322
|
marketplaceName: target.name,
|
|
34329
34323
|
pluginName: bundle.name,
|
|
@@ -34340,7 +34334,7 @@ function resolveRenderablePluginBundles(fleetRoot) {
|
|
|
34340
34334
|
function homeMarketplaceTarget(fleetRoot) {
|
|
34341
34335
|
return {
|
|
34342
34336
|
name: FLEET_MARKETPLACE_NAME,
|
|
34343
|
-
root:
|
|
34337
|
+
root: path28__default.join(fleetRoot, MARKETPLACE_DIR_NAME)
|
|
34344
34338
|
};
|
|
34345
34339
|
}
|
|
34346
34340
|
function groupRenderableBundlesByMarketplace(bundles) {
|
|
@@ -34356,24 +34350,24 @@ function groupRenderableBundlesByMarketplace(bundles) {
|
|
|
34356
34350
|
return groups;
|
|
34357
34351
|
}
|
|
34358
34352
|
function renderPluginRoot(pluginRoot, bundle, options) {
|
|
34359
|
-
const parentRoot =
|
|
34353
|
+
const parentRoot = path28__default.dirname(pluginRoot);
|
|
34360
34354
|
ensurePrivateDir(parentRoot, parentRoot);
|
|
34361
34355
|
const stageParent = createStagingDir(parentRoot);
|
|
34362
|
-
const stagedPluginRoot =
|
|
34356
|
+
const stagedPluginRoot = path28__default.join(stageParent, path28__default.basename(pluginRoot));
|
|
34363
34357
|
try {
|
|
34364
34358
|
ensurePrivateDir(stagedPluginRoot, stagedPluginRoot);
|
|
34365
|
-
writePrivateJson(
|
|
34359
|
+
writePrivateJson(path28__default.join(stagedPluginRoot, ".claude-plugin", "plugin.json"), claudeManifest(bundle), stagedPluginRoot);
|
|
34366
34360
|
switch (bundle.source) {
|
|
34367
34361
|
case "asset":
|
|
34368
34362
|
if (options.cliId === "claude") {
|
|
34369
|
-
ensurePrivateDir(
|
|
34363
|
+
ensurePrivateDir(path28__default.join(stagedPluginRoot, "agents"), stagedPluginRoot);
|
|
34370
34364
|
}
|
|
34371
|
-
ensurePrivateDir(
|
|
34372
|
-
renderAssetPluginRoot(stagedPluginRoot, bundle, options);
|
|
34365
|
+
ensurePrivateDir(path28__default.join(stagedPluginRoot, "skills"), stagedPluginRoot);
|
|
34366
|
+
renderAssetPluginRoot(stagedPluginRoot, bundle, { ...options, installedPluginRoot: pluginRoot });
|
|
34373
34367
|
break;
|
|
34374
34368
|
}
|
|
34375
|
-
writePrivateJson(
|
|
34376
|
-
writePrivateJson(
|
|
34369
|
+
writePrivateJson(path28__default.join(stagedPluginRoot, ".codex-plugin", "plugin.json"), codexManifest(bundle, stagedPluginRoot), stagedPluginRoot);
|
|
34370
|
+
writePrivateJson(path28__default.join(stagedPluginRoot, ".cursor-plugin", "plugin.json"), cursorManifest(bundle, stagedPluginRoot), stagedPluginRoot);
|
|
34377
34371
|
removePrivatePath(pluginRoot, parentRoot);
|
|
34378
34372
|
renameSync(stagedPluginRoot, pluginRoot);
|
|
34379
34373
|
} finally {
|
|
@@ -34385,13 +34379,13 @@ function renderMarketplaceRoot(target, bundles) {
|
|
|
34385
34379
|
ensurePrivateDir(marketplaceRoot, marketplaceRoot);
|
|
34386
34380
|
const stagedRoot = createStagingDir(marketplaceRoot);
|
|
34387
34381
|
try {
|
|
34388
|
-
writePrivateJson(
|
|
34389
|
-
writePrivateJson(
|
|
34390
|
-
writePrivateJson(
|
|
34382
|
+
writePrivateJson(path28__default.join(stagedRoot, ".agents", "plugins", "marketplace.json"), codexMarketplace(target, bundles), stagedRoot);
|
|
34383
|
+
writePrivateJson(path28__default.join(stagedRoot, ".claude-plugin", "marketplace.json"), claudeMarketplace(target, bundles), stagedRoot);
|
|
34384
|
+
writePrivateJson(path28__default.join(stagedRoot, ".cursor-plugin", "marketplace.json"), cursorMarketplace(target, bundles), stagedRoot);
|
|
34391
34385
|
pruneMarketplaceRoot(target);
|
|
34392
34386
|
pruneStalePluginDirs(target, bundles);
|
|
34393
34387
|
for (const entry of readdirSync(stagedRoot)) {
|
|
34394
|
-
renameSync(
|
|
34388
|
+
renameSync(path28__default.join(stagedRoot, entry), path28__default.join(marketplaceRoot, entry));
|
|
34395
34389
|
}
|
|
34396
34390
|
} finally {
|
|
34397
34391
|
cleanupPrivateRoot(stagedRoot, marketplaceRoot);
|
|
@@ -34399,22 +34393,22 @@ function renderMarketplaceRoot(target, bundles) {
|
|
|
34399
34393
|
}
|
|
34400
34394
|
function pruneMarketplaceRoot(target) {
|
|
34401
34395
|
for (const entry of MARKETPLACE_PRUNE_ENTRIES) {
|
|
34402
|
-
removePrivatePath(
|
|
34396
|
+
removePrivatePath(path28__default.join(target.root, entry), target.root);
|
|
34403
34397
|
}
|
|
34404
34398
|
}
|
|
34405
34399
|
function pruneStalePluginDirs(target, bundles) {
|
|
34406
|
-
const pluginsDir =
|
|
34400
|
+
const pluginsDir = path28__default.join(target.root, PLUGIN_BUNDLES_DIR_NAME);
|
|
34407
34401
|
if (!existsSync(pluginsDir)) return;
|
|
34408
34402
|
const activeDirectoryNames = new Set(bundles.map((bundle) => bundle.directoryName));
|
|
34409
34403
|
for (const entry of readdirSync(pluginsDir)) {
|
|
34410
34404
|
if (activeDirectoryNames.has(entry)) continue;
|
|
34411
|
-
removePrivatePath(
|
|
34405
|
+
removePrivatePath(path28__default.join(pluginsDir, entry), target.root);
|
|
34412
34406
|
}
|
|
34413
34407
|
}
|
|
34414
34408
|
function buildContentHash(target) {
|
|
34415
34409
|
const hash2 = crypto4.createHash("sha256");
|
|
34416
34410
|
for (const filePath of listRenderableFiles(target)) {
|
|
34417
|
-
const relativePath =
|
|
34411
|
+
const relativePath = path28__default.relative(target.root, filePath);
|
|
34418
34412
|
hash2.update(relativePath);
|
|
34419
34413
|
hash2.update("\0");
|
|
34420
34414
|
hash2.update(readFileSync(filePath));
|
|
@@ -34423,14 +34417,14 @@ function buildContentHash(target) {
|
|
|
34423
34417
|
return hash2.digest("hex");
|
|
34424
34418
|
}
|
|
34425
34419
|
function createStagingDir(rootPath) {
|
|
34426
|
-
const stageRoot = mkdtempSync(
|
|
34420
|
+
const stageRoot = mkdtempSync(path28__default.join(rootPath, `.fleet-stage-${process.pid}-${Date.now()}-`));
|
|
34427
34421
|
return stageRoot;
|
|
34428
34422
|
}
|
|
34429
34423
|
function listRenderableFiles(target) {
|
|
34430
34424
|
const files = [];
|
|
34431
34425
|
const ancestorRealDirs = /* @__PURE__ */ new Set();
|
|
34432
34426
|
for (const entry of MARKETPLACE_MANAGED_ENTRIES) {
|
|
34433
|
-
const entryPath =
|
|
34427
|
+
const entryPath = path28__default.join(target.root, entry);
|
|
34434
34428
|
if (!existsSync(entryPath)) continue;
|
|
34435
34429
|
collectRenderableFiles(target.root, entryPath, files, ancestorRealDirs);
|
|
34436
34430
|
}
|
|
@@ -34441,8 +34435,8 @@ function collectRenderableFiles(rootPath, currentPath, files, ancestorRealDirs)
|
|
|
34441
34435
|
if (ancestorRealDirs.has(realDir)) return;
|
|
34442
34436
|
ancestorRealDirs.add(realDir);
|
|
34443
34437
|
for (const entry of readdirSync(currentPath)) {
|
|
34444
|
-
const entryPath =
|
|
34445
|
-
const relativePath =
|
|
34438
|
+
const entryPath = path28__default.join(currentPath, entry);
|
|
34439
|
+
const relativePath = path28__default.relative(rootPath, entryPath);
|
|
34446
34440
|
if (HASH_IGNORED_RELATIVE_PATHS.has(relativePath)) continue;
|
|
34447
34441
|
const stat3 = lstatSync(entryPath);
|
|
34448
34442
|
if (stat3.isSymbolicLink()) {
|
|
@@ -34519,7 +34513,7 @@ function cursorMarketplace(target, bundles) {
|
|
|
34519
34513
|
};
|
|
34520
34514
|
}
|
|
34521
34515
|
function pluginRootForTarget(target, bundle) {
|
|
34522
|
-
return
|
|
34516
|
+
return path28__default.join(target.root, PLUGIN_BUNDLES_DIR_NAME, bundle.directoryName);
|
|
34523
34517
|
}
|
|
34524
34518
|
function marketplacePluginPath(target, bundle) {
|
|
34525
34519
|
return `./${PLUGIN_BUNDLES_DIR_NAME}/${bundle.directoryName}`;
|
|
@@ -34546,7 +34540,7 @@ function cursorManifestVersion(bundle, pluginRoot) {
|
|
|
34546
34540
|
hash2.update(bundle.description);
|
|
34547
34541
|
hash2.update("\0");
|
|
34548
34542
|
for (const filePath of listCursorEffectivePluginFiles(pluginRoot)) {
|
|
34549
|
-
const relativePath =
|
|
34543
|
+
const relativePath = path28__default.relative(pluginRoot, filePath);
|
|
34550
34544
|
hash2.update(relativePath);
|
|
34551
34545
|
hash2.update("\0");
|
|
34552
34546
|
hash2.update(readFileSync(filePath));
|
|
@@ -34561,7 +34555,7 @@ function codexManifestVersion(bundle, pluginRoot) {
|
|
|
34561
34555
|
hash2.update(bundle.description);
|
|
34562
34556
|
hash2.update("\0");
|
|
34563
34557
|
for (const filePath of listCodexEffectivePluginFiles(pluginRoot)) {
|
|
34564
|
-
const relativePath =
|
|
34558
|
+
const relativePath = path28__default.relative(pluginRoot, filePath);
|
|
34565
34559
|
hash2.update(relativePath);
|
|
34566
34560
|
hash2.update("\0");
|
|
34567
34561
|
hash2.update(readFileSync(filePath));
|
|
@@ -34570,7 +34564,7 @@ function codexManifestVersion(bundle, pluginRoot) {
|
|
|
34570
34564
|
return `0.0.0+${hash2.digest("hex").slice(0, 12)}`;
|
|
34571
34565
|
}
|
|
34572
34566
|
function listCodexEffectivePluginFiles(pluginRoot) {
|
|
34573
|
-
const skillsPath =
|
|
34567
|
+
const skillsPath = path28__default.join(pluginRoot, "skills");
|
|
34574
34568
|
if (!existsSync(skillsPath)) return [];
|
|
34575
34569
|
const files = [];
|
|
34576
34570
|
collectRenderableFiles(pluginRoot, skillsPath, files, /* @__PURE__ */ new Set());
|
|
@@ -34578,8 +34572,8 @@ function listCodexEffectivePluginFiles(pluginRoot) {
|
|
|
34578
34572
|
}
|
|
34579
34573
|
function listCursorEffectivePluginFiles(pluginRoot) {
|
|
34580
34574
|
const files = [];
|
|
34581
|
-
for (const entry of ["skills", "
|
|
34582
|
-
const entryPath =
|
|
34575
|
+
for (const entry of ["skills", "hooks", "doctrine.md", "mcp.json"]) {
|
|
34576
|
+
const entryPath = path28__default.join(pluginRoot, entry);
|
|
34583
34577
|
if (!existsSync(entryPath)) continue;
|
|
34584
34578
|
const stat3 = lstatSync(entryPath);
|
|
34585
34579
|
if (stat3.isFile()) {
|
|
@@ -34612,12 +34606,12 @@ async function injectAgentCliProfile(profile, options) {
|
|
|
34612
34606
|
if (!capability.enabled) {
|
|
34613
34607
|
return profile;
|
|
34614
34608
|
}
|
|
34615
|
-
const
|
|
34609
|
+
const enableMetaphor = options.enableMetaphor ?? false;
|
|
34616
34610
|
const endpoint = await options.dedicatedMcpSession.getEndpoint();
|
|
34617
34611
|
const tokenLabel = options.mcpSessionLabel ?? `agent:${profile.id}:${crypto4.randomUUID()}`;
|
|
34618
34612
|
const tokens = await options.dedicatedMcpSession.issueSessionToken({ cwd: profile.cwd, label: tokenLabel });
|
|
34619
34613
|
const mcpServers = buildAgentCliMcpServerConfigs(endpoint.servers, tokens);
|
|
34620
|
-
const doctrine = options.buildSystemPrompt(
|
|
34614
|
+
const doctrine = options.buildSystemPrompt(enableMetaphor);
|
|
34621
34615
|
const tempCleanups = [];
|
|
34622
34616
|
try {
|
|
34623
34617
|
const systemPromptFile = profile.id === "claude" ? writeSystemPromptFile(profile.id, doctrine, (cleanup2) => tempCleanups.push(cleanup2)) : void 0;
|
|
@@ -34652,8 +34646,8 @@ async function injectAgentCliProfile(profile, options) {
|
|
|
34652
34646
|
env: { ...profile.env }
|
|
34653
34647
|
}, requireCodexCommandRunner(options.codexCommandRunner), options.withMarketplaceLock, {
|
|
34654
34648
|
homeMarketplaceName: FLEET_MARKETPLACE_NAME,
|
|
34655
|
-
homeMarketplaceRoot:
|
|
34656
|
-
projectMarketplaceRoot:
|
|
34649
|
+
homeMarketplaceRoot: path28__default.join(options.pluginRootDir ?? options.dataDir ?? getFleetDataDir(), "marketplace"),
|
|
34650
|
+
projectMarketplaceRoot: path28__default.join(profile.cwd, ".fleet")
|
|
34657
34651
|
});
|
|
34658
34652
|
if (cleanupWarning !== void 0) {
|
|
34659
34653
|
launchWarnings.push(`Deprecated Codex plugin cleanup failed: ${cleanupWarning}`);
|
|
@@ -34716,19 +34710,19 @@ function buildAgentCliMcpServerConfigs(endpoints, tokens) {
|
|
|
34716
34710
|
});
|
|
34717
34711
|
}
|
|
34718
34712
|
function writeSystemPromptFile(cliId, systemPrompt, onCleanup) {
|
|
34719
|
-
const tempDir = mkdtempSync(
|
|
34713
|
+
const tempDir = mkdtempSync(path28__default.join(os3__default.tmpdir(), `fleet-${cliId}-`));
|
|
34720
34714
|
onCleanup(() => rmBestEffort(tempDir));
|
|
34721
|
-
const filePath =
|
|
34715
|
+
const filePath = path28__default.join(tempDir, "system-prompt.md");
|
|
34722
34716
|
writeFileSync(filePath, systemPrompt, { encoding: "utf8", flag: "wx", mode: SYSTEM_PROMPT_FILE_MODE });
|
|
34723
34717
|
chmodBestEffort2(filePath, SYSTEM_PROMPT_FILE_MODE);
|
|
34724
34718
|
return filePath;
|
|
34725
34719
|
}
|
|
34726
34720
|
function writeCodexFleetProfile(env, doctrine, pluginKeys, hookExecs) {
|
|
34727
|
-
const codexHome = env.CODEX_HOME ??
|
|
34721
|
+
const codexHome = env.CODEX_HOME ?? path28__default.join(env.HOME ?? os3__default.homedir(), ".codex");
|
|
34728
34722
|
mkdirSync(codexHome, { recursive: true });
|
|
34729
34723
|
pruneLegacyCodexFleetProfiles(codexHome);
|
|
34730
34724
|
const profileName = CODEX_FLEET_PROFILE_NAME;
|
|
34731
|
-
const profilePath =
|
|
34725
|
+
const profilePath = path28__default.join(codexHome, CODEX_FLEET_PROFILE_FILE_NAME);
|
|
34732
34726
|
const hookTrustState = readCodexFleetHookTrustState(profilePath);
|
|
34733
34727
|
writeFileNoFollow2(profilePath, [
|
|
34734
34728
|
CODEX_FLEET_PROFILE_MARKER,
|
|
@@ -34742,7 +34736,7 @@ function writeCodexFleetProfile(env, doctrine, pluginKeys, hookExecs) {
|
|
|
34742
34736
|
"hooks = true",
|
|
34743
34737
|
"",
|
|
34744
34738
|
...pluginKeys.flatMap((pluginKey) => [
|
|
34745
|
-
`[plugins."${
|
|
34739
|
+
`[plugins."${escapeTomlBasicString(pluginKey)}"]`,
|
|
34746
34740
|
"enabled = true",
|
|
34747
34741
|
""
|
|
34748
34742
|
]),
|
|
@@ -34769,7 +34763,7 @@ function codexHooksConfig(hookExecs) {
|
|
|
34769
34763
|
function codexHookHandlersInline(execs) {
|
|
34770
34764
|
const handlers = execs.map((exec) => {
|
|
34771
34765
|
const command = buildPosixShellCommand([exec.command, ...exec.args]);
|
|
34772
|
-
return `{ type = "command", command = "${
|
|
34766
|
+
return `{ type = "command", command = "${escapeTomlBasicString(command)}" }`;
|
|
34773
34767
|
}).join(", ");
|
|
34774
34768
|
return `[{ hooks = [${handlers}] }]`;
|
|
34775
34769
|
}
|
|
@@ -34832,7 +34826,7 @@ function pruneLegacyCodexFleetProfiles(codexHome) {
|
|
|
34832
34826
|
}
|
|
34833
34827
|
for (const entry of entries) {
|
|
34834
34828
|
if (!CODEX_LEGACY_FLEET_PROFILE_FILE_NAME_PATTERN.test(entry)) continue;
|
|
34835
|
-
const filePath =
|
|
34829
|
+
const filePath = path28__default.join(codexHome, entry);
|
|
34836
34830
|
if (!isLegacyFleetCodexProfile(filePath)) continue;
|
|
34837
34831
|
unlinkBestEffort2(filePath);
|
|
34838
34832
|
}
|
|
@@ -34963,6 +34957,18 @@ function createFleetAgentRuntimeLifecycle(deps) {
|
|
|
34963
34957
|
}
|
|
34964
34958
|
};
|
|
34965
34959
|
}
|
|
34960
|
+
function createAuthEnvResolver(globalOptionsService) {
|
|
34961
|
+
return async (cli) => {
|
|
34962
|
+
if (cli !== "codex" || !globalOptionsService) return {};
|
|
34963
|
+
try {
|
|
34964
|
+
const mode = globalOptionsService.load().codexLaunchMode;
|
|
34965
|
+
if (!mode) return {};
|
|
34966
|
+
return { CODEX_USE_ACP: mode === "app-server" ? "false" : "true" };
|
|
34967
|
+
} catch {
|
|
34968
|
+
return {};
|
|
34969
|
+
}
|
|
34970
|
+
};
|
|
34971
|
+
}
|
|
34966
34972
|
function createFleetAgentRuntimeMcpServices() {
|
|
34967
34973
|
const mcpRegistry = createMcpToolRegistry();
|
|
34968
34974
|
const mcpToolSnapshotStore = createMcpToolSnapshotStore();
|
|
@@ -34992,7 +34998,7 @@ function registerExecutorPort(mcpRegistry, carrierRuntime, isActive) {
|
|
|
34992
34998
|
}
|
|
34993
34999
|
function registerFleetAgentRuntimeTools(mcpRegistry, carrierRuntime, deps) {
|
|
34994
35000
|
registerAgentToolDefaults(mcpRegistry, carrierRuntime, {
|
|
34995
|
-
authEnvResolver:
|
|
35001
|
+
authEnvResolver: createAuthEnvResolver(deps.globalOptionsService),
|
|
34996
35002
|
reservedExternalMcpServerIds: buildReservedExternalMcpServerIds(deps.reservedExternalMcpServerIds),
|
|
34997
35003
|
workspaceChangeScanner: deps.workspaceChangeScanner
|
|
34998
35004
|
});
|
|
@@ -35285,7 +35291,7 @@ function extractLegacyMarkdownWikiLinks(body, wikiDir, basePath) {
|
|
|
35285
35291
|
}
|
|
35286
35292
|
function resolveLegacyWikiTarget(target, wikiDir, basePath) {
|
|
35287
35293
|
if (!target || target.startsWith("#")) return null;
|
|
35288
|
-
if (
|
|
35294
|
+
if (path28__default.isAbsolute(target)) return null;
|
|
35289
35295
|
if (/^[a-z][a-z0-9+.-]*:/i.test(target)) return null;
|
|
35290
35296
|
const withoutFragment = target.split("#", 1)[0]?.split("?", 1)[0] ?? "";
|
|
35291
35297
|
if (!withoutFragment.endsWith(".md")) return null;
|
|
@@ -35295,12 +35301,12 @@ function resolveLegacyWikiTarget(target, wikiDir, basePath) {
|
|
|
35295
35301
|
} catch {
|
|
35296
35302
|
return null;
|
|
35297
35303
|
}
|
|
35298
|
-
const resolved =
|
|
35299
|
-
const relative =
|
|
35300
|
-
if (!relative || relative.startsWith("..") ||
|
|
35304
|
+
const resolved = path28__default.resolve(path28__default.dirname(basePath), decodedTarget);
|
|
35305
|
+
const relative = path28__default.relative(wikiDir, resolved);
|
|
35306
|
+
if (!relative || relative.startsWith("..") || path28__default.isAbsolute(relative)) return null;
|
|
35301
35307
|
return {
|
|
35302
35308
|
target,
|
|
35303
|
-
entryId:
|
|
35309
|
+
entryId: path28__default.basename(relative, ".md")
|
|
35304
35310
|
};
|
|
35305
35311
|
}
|
|
35306
35312
|
|
|
@@ -35560,18 +35566,18 @@ Always read \`schema/wiki-schema.md\` directly before composing or revising entr
|
|
|
35560
35566
|
`;
|
|
35561
35567
|
async function ensureWorkspaceSchema(paths) {
|
|
35562
35568
|
await mkdir(paths.schemaDir, { recursive: true });
|
|
35563
|
-
await writeDefaultFileIfMissing(
|
|
35564
|
-
await writeDefaultFileIfMissing(
|
|
35569
|
+
await writeDefaultFileIfMissing(path28__default.join(paths.schemaDir, WORKSPACE_SCHEMA_AGENTS_FILENAME), DEFAULT_WORKSPACE_SCHEMA_AGENTS);
|
|
35570
|
+
await writeDefaultFileIfMissing(path28__default.join(paths.schemaDir, WORKSPACE_SCHEMA_FILENAME), DEFAULT_WORKSPACE_WIKI_SCHEMA);
|
|
35565
35571
|
await writeDefaultFileIfMissing(buildTemplatePath(paths, "prd"), DEFAULT_TEMPLATE_PRD);
|
|
35566
35572
|
return readWorkspaceSchemaSummary(paths);
|
|
35567
35573
|
}
|
|
35568
35574
|
async function ensureWorkspaceDoctrine(paths) {
|
|
35569
35575
|
await mkdir(paths.root, { recursive: true });
|
|
35570
|
-
await writeDefaultFileIfMissing(
|
|
35576
|
+
await writeDefaultFileIfMissing(path28__default.join(paths.root, WORKSPACE_KNOWLEDGE_AGENTS_FILENAME), DEFAULT_WORKSPACE_KNOWLEDGE_AGENTS);
|
|
35571
35577
|
}
|
|
35572
35578
|
async function readWorkspaceSchemaSummary(paths) {
|
|
35573
|
-
const agentsPath =
|
|
35574
|
-
const wikiSchemaPath =
|
|
35579
|
+
const agentsPath = path28__default.join(paths.schemaDir, WORKSPACE_SCHEMA_AGENTS_FILENAME);
|
|
35580
|
+
const wikiSchemaPath = path28__default.join(paths.schemaDir, WORKSPACE_SCHEMA_FILENAME);
|
|
35575
35581
|
const wikiSchemaContent = await tryReadFile(wikiSchemaPath);
|
|
35576
35582
|
const templates = await scanTemplates(paths);
|
|
35577
35583
|
if (wikiSchemaContent === null) {
|
|
@@ -35610,7 +35616,7 @@ async function scanTemplates(paths) {
|
|
|
35610
35616
|
if (!entry.name.startsWith(WORKSPACE_TEMPLATE_PREFIX) || !entry.name.endsWith(WORKSPACE_TEMPLATE_SUFFIX)) continue;
|
|
35611
35617
|
const id = entry.name.slice(WORKSPACE_TEMPLATE_PREFIX.length, -WORKSPACE_TEMPLATE_SUFFIX.length);
|
|
35612
35618
|
if (!id) continue;
|
|
35613
|
-
const filePath =
|
|
35619
|
+
const filePath = path28__default.join(paths.schemaDir, entry.name);
|
|
35614
35620
|
try {
|
|
35615
35621
|
const parsed = parseTemplateMarkdown(await readFile(filePath, "utf8"));
|
|
35616
35622
|
templates.push({
|
|
@@ -35644,7 +35650,7 @@ async function validateTemplateCompliance(paths, templateId, body) {
|
|
|
35644
35650
|
}
|
|
35645
35651
|
}
|
|
35646
35652
|
function inferTemplateIdFromTarget(target, knownTemplateIds) {
|
|
35647
|
-
const basename =
|
|
35653
|
+
const basename = path28__default.basename(target, ".md");
|
|
35648
35654
|
const ids = knownTemplateIds ?? DEFAULT_TEMPLATE_IDS;
|
|
35649
35655
|
const sorted = [...ids].sort((a, b) => b.length - a.length);
|
|
35650
35656
|
for (const id of sorted) {
|
|
@@ -35673,7 +35679,7 @@ function extractSchemaSummary(content) {
|
|
|
35673
35679
|
return lines.find((line) => line.length > 0 && !line.startsWith("#")) ?? "Workspace schema is present.";
|
|
35674
35680
|
}
|
|
35675
35681
|
function buildTemplatePath(paths, id) {
|
|
35676
|
-
return
|
|
35682
|
+
return path28__default.join(paths.schemaDir, `${WORKSPACE_TEMPLATE_PREFIX}${id}${WORKSPACE_TEMPLATE_SUFFIX}`);
|
|
35677
35683
|
}
|
|
35678
35684
|
function parseTemplateMarkdown(content) {
|
|
35679
35685
|
const normalized = content.replace(/\r\n/g, "\n");
|
|
@@ -35700,16 +35706,16 @@ function isAlreadyExistsError(error51) {
|
|
|
35700
35706
|
|
|
35701
35707
|
// ../../packages/fleet-wiki/src/paths.ts
|
|
35702
35708
|
function resolveMemoryPaths(cwd) {
|
|
35703
|
-
const root =
|
|
35709
|
+
const root = path28__default.join(cwd, KNOWLEDGE_ROOT_DIRNAME);
|
|
35704
35710
|
return {
|
|
35705
35711
|
root,
|
|
35706
|
-
rawDir:
|
|
35707
|
-
wikiDir:
|
|
35708
|
-
schemaDir:
|
|
35709
|
-
queueDir:
|
|
35710
|
-
archiveDir:
|
|
35711
|
-
conflictsDir:
|
|
35712
|
-
indexFile:
|
|
35712
|
+
rawDir: path28__default.join(root, RAW_DIRNAME),
|
|
35713
|
+
wikiDir: path28__default.join(root, WIKI_DIRNAME),
|
|
35714
|
+
schemaDir: path28__default.join(root, SCHEMA_DIRNAME),
|
|
35715
|
+
queueDir: path28__default.join(root, QUEUE_DIRNAME),
|
|
35716
|
+
archiveDir: path28__default.join(root, ARCHIVE_DIRNAME),
|
|
35717
|
+
conflictsDir: path28__default.join(root, CONFLICTS_DIRNAME),
|
|
35718
|
+
indexFile: path28__default.join(root, INDEX_FILENAME)
|
|
35713
35719
|
};
|
|
35714
35720
|
}
|
|
35715
35721
|
async function ensureMemoryRoot(paths) {
|
|
@@ -35724,10 +35730,10 @@ async function ensureMemoryRoot(paths) {
|
|
|
35724
35730
|
await ensureWorkspaceDoctrine(paths);
|
|
35725
35731
|
}
|
|
35726
35732
|
function getIndexMarkdownFile(paths) {
|
|
35727
|
-
return
|
|
35733
|
+
return path28__default.join(paths.wikiDir, INDEX_MD_FILENAME);
|
|
35728
35734
|
}
|
|
35729
35735
|
function getLogFile(paths) {
|
|
35730
|
-
return
|
|
35736
|
+
return path28__default.join(paths.root, LOG_MD_FILENAME);
|
|
35731
35737
|
}
|
|
35732
35738
|
|
|
35733
35739
|
// ../../packages/fleet-wiki/src/log.ts
|
|
@@ -35891,12 +35897,12 @@ async function readWikiEntry(id, paths) {
|
|
|
35891
35897
|
const index = await loadIndex(paths);
|
|
35892
35898
|
const indexed = index[id];
|
|
35893
35899
|
if (indexed) {
|
|
35894
|
-
const resolved =
|
|
35895
|
-
const rel =
|
|
35896
|
-
if (!rel || rel.startsWith("..") ||
|
|
35900
|
+
const resolved = path28__default.resolve(paths.root, indexed.path);
|
|
35901
|
+
const rel = path28__default.relative(paths.wikiDir, resolved);
|
|
35902
|
+
if (!rel || rel.startsWith("..") || path28__default.isAbsolute(rel)) return null;
|
|
35897
35903
|
return readMarkdownFile(resolved);
|
|
35898
35904
|
}
|
|
35899
|
-
const fallbackPath =
|
|
35905
|
+
const fallbackPath = path28__default.join(paths.wikiDir, `${id}.md`);
|
|
35900
35906
|
if (await pathExists(fallbackPath)) {
|
|
35901
35907
|
return readMarkdownFile(fallbackPath);
|
|
35902
35908
|
}
|
|
@@ -35907,20 +35913,20 @@ async function readWikiEntry(id, paths) {
|
|
|
35907
35913
|
async function writeWikiEntryAtTarget(entry, target, paths) {
|
|
35908
35914
|
await ensureMemoryRoot(paths);
|
|
35909
35915
|
assertSafeEntryId(entry.id);
|
|
35910
|
-
const absoluteTarget =
|
|
35911
|
-
const relativeTarget =
|
|
35912
|
-
if (!relativeTarget || relativeTarget.startsWith("..") ||
|
|
35916
|
+
const absoluteTarget = path28__default.resolve(paths.root, target);
|
|
35917
|
+
const relativeTarget = path28__default.relative(paths.wikiDir, absoluteTarget);
|
|
35918
|
+
if (!relativeTarget || relativeTarget.startsWith("..") || path28__default.isAbsolute(relativeTarget)) {
|
|
35913
35919
|
throw new Error(`[fleet-wiki] wiki target escapes wiki/: ${target}`);
|
|
35914
35920
|
}
|
|
35915
35921
|
if (!absoluteTarget.endsWith(".md")) {
|
|
35916
35922
|
throw new Error(`[fleet-wiki] wiki target must end with .md: ${target}`);
|
|
35917
35923
|
}
|
|
35918
|
-
if (
|
|
35924
|
+
if (path28__default.basename(absoluteTarget, ".md") !== entry.id) {
|
|
35919
35925
|
throw new Error("wiki patch body id must match target filename");
|
|
35920
35926
|
}
|
|
35921
|
-
await mkdir(
|
|
35927
|
+
await mkdir(path28__default.dirname(absoluteTarget), { recursive: true });
|
|
35922
35928
|
await writeMarkdownAtomic(absoluteTarget, serializeWikiEntry(entry), paths);
|
|
35923
|
-
return
|
|
35929
|
+
return path28__default.join("wiki", relativeTarget).replaceAll(path28__default.sep, "/");
|
|
35924
35930
|
}
|
|
35925
35931
|
async function writeRawSourceEntry(entry, paths) {
|
|
35926
35932
|
await ensureMemoryRoot(paths);
|
|
@@ -35939,11 +35945,11 @@ async function writeRawSourceEntry(entry, paths) {
|
|
|
35939
35945
|
},
|
|
35940
35946
|
entry.content
|
|
35941
35947
|
);
|
|
35942
|
-
await writeMarkdownAtomic(
|
|
35948
|
+
await writeMarkdownAtomic(path28__default.join(paths.root, relativePath), content, paths);
|
|
35943
35949
|
return relativePath;
|
|
35944
35950
|
}
|
|
35945
35951
|
async function readRawSourceEntry(rawSourceRef, paths) {
|
|
35946
|
-
const absolutePath =
|
|
35952
|
+
const absolutePath = path28__default.resolve(paths.root, rawSourceRef);
|
|
35947
35953
|
assertWithinRawDir(absolutePath, paths);
|
|
35948
35954
|
const parsed = parseMarkdown(await readFile(absolutePath, "utf8"));
|
|
35949
35955
|
return {
|
|
@@ -36134,8 +36140,8 @@ function computeContentHash(content) {
|
|
|
36134
36140
|
return crypto4.createHash("sha256").update(content, "utf8").digest("hex").slice(0, 8);
|
|
36135
36141
|
}
|
|
36136
36142
|
function assertWithinRawDir(absolutePath, paths) {
|
|
36137
|
-
const relative =
|
|
36138
|
-
if (!relative || relative.startsWith("..") ||
|
|
36143
|
+
const relative = path28__default.relative(paths.rawDir, absolutePath);
|
|
36144
|
+
if (!relative || relative.startsWith("..") || path28__default.isAbsolute(relative)) {
|
|
36139
36145
|
throw new Error(`[fleet-wiki] raw source ref escapes raw/: ${absolutePath}`);
|
|
36140
36146
|
}
|
|
36141
36147
|
}
|
|
@@ -36191,7 +36197,7 @@ function parseWikiEntry(content) {
|
|
|
36191
36197
|
async function listWikiRecords(paths) {
|
|
36192
36198
|
return listMarkdownEntriesRecursive(paths.wikiDir, paths, (content, filePath) => ({
|
|
36193
36199
|
entry: parseWikiEntry(content),
|
|
36194
|
-
path:
|
|
36200
|
+
path: path28__default.relative(paths.root, filePath).replaceAll(path28__default.sep, "/")
|
|
36195
36201
|
}));
|
|
36196
36202
|
}
|
|
36197
36203
|
async function listMarkdownEntriesRecursive(dirPath, paths, parser) {
|
|
@@ -36204,7 +36210,7 @@ async function listMarkdownEntriesRecursive(dirPath, paths, parser) {
|
|
|
36204
36210
|
}
|
|
36205
36211
|
const sortedEntries = entries.sort((left, right) => left.name.localeCompare(right.name));
|
|
36206
36212
|
for (const entry of sortedEntries) {
|
|
36207
|
-
const filePath =
|
|
36213
|
+
const filePath = path28__default.join(dirPath, entry.name);
|
|
36208
36214
|
if (entry.isDirectory()) {
|
|
36209
36215
|
items.push(...await listMarkdownEntriesRecursive(filePath, paths, parser));
|
|
36210
36216
|
continue;
|
|
@@ -36342,8 +36348,8 @@ async function writeJsonAtomic(filePath, value, paths) {
|
|
|
36342
36348
|
}
|
|
36343
36349
|
async function writeAtomic(filePath, content, paths) {
|
|
36344
36350
|
await ensureMemoryRoot(paths);
|
|
36345
|
-
const tempPath =
|
|
36346
|
-
|
|
36351
|
+
const tempPath = path28__default.join(
|
|
36352
|
+
path28__default.dirname(filePath),
|
|
36347
36353
|
`.tmp-${process.pid}-${Date.now()}-${crypto4.randomUUID()}-${os3__default.hostname()}`
|
|
36348
36354
|
);
|
|
36349
36355
|
await writeFile(tempPath, content, "utf8");
|
|
@@ -36390,7 +36396,7 @@ async function enhancedSearch(paths, options) {
|
|
|
36390
36396
|
for (const entry of entries) {
|
|
36391
36397
|
if (!index[entry.id]) {
|
|
36392
36398
|
index[entry.id] = {
|
|
36393
|
-
path:
|
|
36399
|
+
path: path28__default.join("wiki", `${entry.id}.md`),
|
|
36394
36400
|
title: entry.title,
|
|
36395
36401
|
tags: entry.tags,
|
|
36396
36402
|
updated: entry.updated
|
|
@@ -36526,7 +36532,7 @@ function toEnhancedHit(entry, signals) {
|
|
|
36526
36532
|
score: enhancedScore,
|
|
36527
36533
|
reason: signals.legacyReason ?? "body",
|
|
36528
36534
|
excerpt,
|
|
36529
|
-
path:
|
|
36535
|
+
path: path28__default.join("wiki", `${entry.id}.md`),
|
|
36530
36536
|
tags: entry.tags,
|
|
36531
36537
|
updated: entry.updated,
|
|
36532
36538
|
version: entry.version,
|
|
@@ -36722,7 +36728,7 @@ function toRankedHit(entry, reason, detail, graphBoost, backlinksById) {
|
|
|
36722
36728
|
score: basePriority * 100 + statusPriority * 10 + graphScore + (detail.tagBoost ?? 0),
|
|
36723
36729
|
reason,
|
|
36724
36730
|
excerpt,
|
|
36725
|
-
path:
|
|
36731
|
+
path: path28__default.join("wiki", `${entry.id}.md`),
|
|
36726
36732
|
tags: entry.tags,
|
|
36727
36733
|
updated: entry.updated,
|
|
36728
36734
|
version: entry.version,
|
|
@@ -37150,15 +37156,15 @@ var PATCH_SET_DIRNAME = "_sets";
|
|
|
37150
37156
|
var PATCH_SET_META_FILENAME = PATCH_META_FILENAME;
|
|
37151
37157
|
function getPatchSetDir(paths, patchSetId) {
|
|
37152
37158
|
assertSafePatchSetId(patchSetId);
|
|
37153
|
-
const patchSetDir =
|
|
37154
|
-
const relative =
|
|
37155
|
-
if (!relative || relative.startsWith("..") ||
|
|
37159
|
+
const patchSetDir = path28__default.join(paths.queueDir, PATCH_SET_DIRNAME, patchSetId);
|
|
37160
|
+
const relative = path28__default.relative(path28__default.join(paths.queueDir, PATCH_SET_DIRNAME), patchSetDir);
|
|
37161
|
+
if (!relative || relative.startsWith("..") || path28__default.isAbsolute(relative)) {
|
|
37156
37162
|
throw new Error(`[fleet-wiki] patch set id escapes queue/_sets: ${patchSetId}`);
|
|
37157
37163
|
}
|
|
37158
37164
|
return patchSetDir;
|
|
37159
37165
|
}
|
|
37160
37166
|
function getPatchSetMetaFile(paths, patchSetId) {
|
|
37161
|
-
return
|
|
37167
|
+
return path28__default.join(getPatchSetDir(paths, patchSetId), PATCH_SET_META_FILENAME);
|
|
37162
37168
|
}
|
|
37163
37169
|
function buildPatchSetId(createdAt, sourceRef) {
|
|
37164
37170
|
const compact = createdAt.replace(/[:.]/g, "-");
|
|
@@ -37191,7 +37197,7 @@ async function createConflict(input, paths) {
|
|
|
37191
37197
|
await ensureMemoryRoot(paths);
|
|
37192
37198
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
37193
37199
|
const conflictId = buildConflictId(now, input.wikiId, input.reason, input.proposed);
|
|
37194
|
-
const conflictDir =
|
|
37200
|
+
const conflictDir = path28__default.join(paths.conflictsDir, conflictId);
|
|
37195
37201
|
await mkdir(conflictDir, { recursive: true });
|
|
37196
37202
|
const meta3 = {
|
|
37197
37203
|
id: conflictId,
|
|
@@ -37211,13 +37217,13 @@ async function createConflict(input, paths) {
|
|
|
37211
37217
|
currentHash: input.currentHash,
|
|
37212
37218
|
warnings: input.warnings
|
|
37213
37219
|
};
|
|
37214
|
-
await writeJsonFile(
|
|
37215
|
-
await writePatchFile(
|
|
37220
|
+
await writeJsonFile(path28__default.join(conflictDir, CONFLICT_META_FILENAME), meta3, paths);
|
|
37221
|
+
await writePatchFile(path28__default.join(conflictDir, CONFLICT_PROPOSED_FILENAME), input.proposed, paths);
|
|
37216
37222
|
if (input.current !== void 0) {
|
|
37217
|
-
await writePatchFile(
|
|
37223
|
+
await writePatchFile(path28__default.join(conflictDir, CONFLICT_CURRENT_FILENAME), input.current, paths);
|
|
37218
37224
|
}
|
|
37219
37225
|
if (input.rawSource !== void 0) {
|
|
37220
|
-
await writePatchFile(
|
|
37226
|
+
await writePatchFile(path28__default.join(conflictDir, CONFLICT_RAW_SOURCE_FILENAME), input.rawSource, paths);
|
|
37221
37227
|
}
|
|
37222
37228
|
return {
|
|
37223
37229
|
meta: meta3,
|
|
@@ -37231,7 +37237,7 @@ async function listConflicts(paths) {
|
|
|
37231
37237
|
const metas = [];
|
|
37232
37238
|
for (const id of ids) {
|
|
37233
37239
|
try {
|
|
37234
|
-
metas.push(await readJsonFile2(
|
|
37240
|
+
metas.push(await readJsonFile2(path28__default.join(paths.conflictsDir, id, CONFLICT_META_FILENAME)));
|
|
37235
37241
|
} catch {
|
|
37236
37242
|
continue;
|
|
37237
37243
|
}
|
|
@@ -37240,13 +37246,13 @@ async function listConflicts(paths) {
|
|
|
37240
37246
|
}
|
|
37241
37247
|
async function readConflict(conflictId, paths) {
|
|
37242
37248
|
const conflictDir = resolveConflictDir(conflictId, paths);
|
|
37243
|
-
const meta3 = await readJsonFile2(
|
|
37244
|
-
const currentPath =
|
|
37245
|
-
const rawSourcePath =
|
|
37249
|
+
const meta3 = await readJsonFile2(path28__default.join(conflictDir, CONFLICT_META_FILENAME));
|
|
37250
|
+
const currentPath = path28__default.join(conflictDir, CONFLICT_CURRENT_FILENAME);
|
|
37251
|
+
const rawSourcePath = path28__default.join(conflictDir, CONFLICT_RAW_SOURCE_FILENAME);
|
|
37246
37252
|
return {
|
|
37247
37253
|
meta: meta3,
|
|
37248
37254
|
current: await pathExists(currentPath) ? await readPatchFile(currentPath) : void 0,
|
|
37249
|
-
proposed: await readPatchFile(
|
|
37255
|
+
proposed: await readPatchFile(path28__default.join(conflictDir, CONFLICT_PROPOSED_FILENAME)),
|
|
37250
37256
|
rawSource: await pathExists(rawSourcePath) ? await readPatchFile(rawSourcePath) : void 0
|
|
37251
37257
|
};
|
|
37252
37258
|
}
|
|
@@ -37265,9 +37271,9 @@ function sanitizeConflictToken(value) {
|
|
|
37265
37271
|
return value.toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64) || "unknown";
|
|
37266
37272
|
}
|
|
37267
37273
|
function resolveConflictDir(conflictId, paths) {
|
|
37268
|
-
const conflictDir =
|
|
37269
|
-
const relative =
|
|
37270
|
-
if (!relative || relative.startsWith("..") ||
|
|
37274
|
+
const conflictDir = path28__default.resolve(paths.conflictsDir, conflictId);
|
|
37275
|
+
const relative = path28__default.relative(paths.conflictsDir, conflictDir);
|
|
37276
|
+
if (!relative || relative.startsWith("..") || path28__default.isAbsolute(relative)) {
|
|
37271
37277
|
throw new Error(`[fleet-wiki] conflict id escapes conflicts/: ${conflictId}`);
|
|
37272
37278
|
}
|
|
37273
37279
|
return conflictDir;
|
|
@@ -37305,11 +37311,11 @@ async function validatePatch(patch, paths) {
|
|
|
37305
37311
|
if (!target || !summary || !proposer || !created) throw new Error("patch frontmatter is incomplete");
|
|
37306
37312
|
if (summary.length > 120) throw new Error("patch summary exceeds 120 chars");
|
|
37307
37313
|
assertCanonicalPatchTarget(target);
|
|
37308
|
-
const absoluteTarget =
|
|
37309
|
-
if (!absoluteTarget.startsWith(`${paths.root}${
|
|
37314
|
+
const absoluteTarget = path28__default.resolve(paths.root, target);
|
|
37315
|
+
if (!absoluteTarget.startsWith(`${paths.root}${path28__default.sep}`) && absoluteTarget !== paths.root) {
|
|
37310
37316
|
throw new Error("patch target escapes wiki root");
|
|
37311
37317
|
}
|
|
37312
|
-
if (!absoluteTarget.startsWith(`${paths.wikiDir}${
|
|
37318
|
+
if (!absoluteTarget.startsWith(`${paths.wikiDir}${path28__default.sep}`)) throw new Error("wiki patch must target wiki/");
|
|
37313
37319
|
assertNoSymlinkPathComponents(target, paths);
|
|
37314
37320
|
if (op === "create_wiki" && await pathExists(absoluteTarget)) {
|
|
37315
37321
|
throw new Error(
|
|
@@ -37330,19 +37336,19 @@ async function applyPatch(patch, paths) {
|
|
|
37330
37336
|
async function enqueuePatch(patch, paths, metaOverrides) {
|
|
37331
37337
|
await ensureMemoryRoot(paths);
|
|
37332
37338
|
const patchId = buildPatchId(patch.frontmatter.created, patch.frontmatter.summary, patch.frontmatter.target, patch.body);
|
|
37333
|
-
const queueDir =
|
|
37339
|
+
const queueDir = path28__default.join(paths.queueDir, patchId);
|
|
37334
37340
|
if (await pathExists(queueDir)) {
|
|
37335
37341
|
throw new Error(`[fleet-wiki] patch id collision: ${patchId} - this should never happen with target+body hashing`);
|
|
37336
37342
|
}
|
|
37337
37343
|
await mkdir(queueDir, { recursive: true });
|
|
37338
|
-
await writePatchFile(
|
|
37344
|
+
await writePatchFile(path28__default.join(queueDir, PATCH_FILENAME), serializePatch(patch), paths);
|
|
37339
37345
|
const meta3 = {
|
|
37340
37346
|
id: patchId,
|
|
37341
37347
|
status: "pending",
|
|
37342
37348
|
createdAt: patch.frontmatter.created,
|
|
37343
37349
|
...metaOverrides
|
|
37344
37350
|
};
|
|
37345
|
-
await writeJsonFile(
|
|
37351
|
+
await writeJsonFile(path28__default.join(queueDir, PATCH_META_FILENAME), meta3, paths);
|
|
37346
37352
|
await appendLog(paths, "patch enqueued", {
|
|
37347
37353
|
patch_id: patchId,
|
|
37348
37354
|
patch_set_id: meta3.patch_set_id ?? null,
|
|
@@ -37360,7 +37366,7 @@ async function listQueue(paths) {
|
|
|
37360
37366
|
for (const id of ids) {
|
|
37361
37367
|
if (id === "_sets") continue;
|
|
37362
37368
|
try {
|
|
37363
|
-
const meta3 = await readJsonFile2(
|
|
37369
|
+
const meta3 = await readJsonFile2(path28__default.join(paths.queueDir, id, PATCH_META_FILENAME));
|
|
37364
37370
|
results.push({ id, meta: meta3 });
|
|
37365
37371
|
} catch {
|
|
37366
37372
|
continue;
|
|
@@ -37385,17 +37391,17 @@ async function resolveQueueSelection(id, paths) {
|
|
|
37385
37391
|
}
|
|
37386
37392
|
async function showQueue(id, paths) {
|
|
37387
37393
|
const selection = await resolveQueueSelection(id, paths);
|
|
37388
|
-
const queueDir =
|
|
37389
|
-
const patch = await parsePatch(await readPatchFile(
|
|
37390
|
-
const meta3 = await readJsonFile2(
|
|
37394
|
+
const queueDir = path28__default.join(paths.queueDir, selection.id);
|
|
37395
|
+
const patch = await parsePatch(await readPatchFile(path28__default.join(queueDir, PATCH_FILENAME)));
|
|
37396
|
+
const meta3 = await readJsonFile2(path28__default.join(queueDir, PATCH_META_FILENAME));
|
|
37391
37397
|
return { patch, meta: meta3 };
|
|
37392
37398
|
}
|
|
37393
37399
|
async function rewriteQueuedPatch(id, paths, patch, meta3, expectedPatchHash) {
|
|
37394
37400
|
assertSafeQueueId(id);
|
|
37395
37401
|
return withPatchEditLock(paths, id, async () => {
|
|
37396
|
-
const queueDir =
|
|
37402
|
+
const queueDir = path28__default.join(paths.queueDir, id);
|
|
37397
37403
|
if (expectedPatchHash !== void 0) {
|
|
37398
|
-
const currentMarkdown = await readPatchFile(
|
|
37404
|
+
const currentMarkdown = await readPatchFile(path28__default.join(queueDir, PATCH_FILENAME));
|
|
37399
37405
|
const currentHash = computeContentHash(currentMarkdown);
|
|
37400
37406
|
if (currentHash !== expectedPatchHash) {
|
|
37401
37407
|
throw new Error(`[fleet-wiki] wiki_patch_edit stale base_patch_hash: expected ${currentHash}, got ${expectedPatchHash}`);
|
|
@@ -37404,8 +37410,8 @@ async function rewriteQueuedPatch(id, paths, patch, meta3, expectedPatchHash) {
|
|
|
37404
37410
|
const patchMarkdown = serializePatch(patch);
|
|
37405
37411
|
const patchHash = computeContentHash(patchMarkdown);
|
|
37406
37412
|
const nextMeta = { ...meta3, lastEditHash: patchHash };
|
|
37407
|
-
await writePatchFile(
|
|
37408
|
-
await writeJsonFile(
|
|
37413
|
+
await writePatchFile(path28__default.join(queueDir, PATCH_FILENAME), patchMarkdown, paths);
|
|
37414
|
+
await writeJsonFile(path28__default.join(queueDir, PATCH_META_FILENAME), nextMeta, paths);
|
|
37409
37415
|
return patchHash;
|
|
37410
37416
|
});
|
|
37411
37417
|
}
|
|
@@ -37429,8 +37435,8 @@ async function approvePatch(id, paths) {
|
|
|
37429
37435
|
rawSourceRef: meta3.rawSourceRef,
|
|
37430
37436
|
warnings: meta3.warnings
|
|
37431
37437
|
});
|
|
37432
|
-
const queueDir =
|
|
37433
|
-
await writeJsonFile(
|
|
37438
|
+
const queueDir = path28__default.join(paths.queueDir, id);
|
|
37439
|
+
await writeJsonFile(path28__default.join(queueDir, PATCH_META_FILENAME), {
|
|
37434
37440
|
...meta3,
|
|
37435
37441
|
conflictId
|
|
37436
37442
|
}, paths);
|
|
@@ -37466,7 +37472,7 @@ async function approvePatchSet(patchSetId, paths) {
|
|
|
37466
37472
|
const failed = [];
|
|
37467
37473
|
const missing = [];
|
|
37468
37474
|
for (const patchId of patchSet.patchIds) {
|
|
37469
|
-
const queueDir =
|
|
37475
|
+
const queueDir = path28__default.join(paths.queueDir, patchId);
|
|
37470
37476
|
if (!await pathExists(queueDir)) {
|
|
37471
37477
|
missing.push(patchId);
|
|
37472
37478
|
continue;
|
|
@@ -37532,7 +37538,7 @@ ${patch.body}`;
|
|
|
37532
37538
|
}
|
|
37533
37539
|
async function normalizeWikiEntryPatch(entry, target, paths) {
|
|
37534
37540
|
assertSafeEntryId(entry.id);
|
|
37535
|
-
if (entry.id !==
|
|
37541
|
+
if (entry.id !== path28__default.basename(target, ".md")) {
|
|
37536
37542
|
throw new Error("wiki patch body id must match target filename");
|
|
37537
37543
|
}
|
|
37538
37544
|
const inlineRawSourceRef = extractInlineRawSourceRef(entry.body);
|
|
@@ -37575,9 +37581,9 @@ function buildPatchId(createdAt, summary, target, body) {
|
|
|
37575
37581
|
}
|
|
37576
37582
|
async function validatePatchBase(patch, meta3, paths) {
|
|
37577
37583
|
if (patch.frontmatter.op !== "update_wiki" || !meta3?.baseVersion && !meta3?.baseHash) return;
|
|
37578
|
-
const wikiId =
|
|
37584
|
+
const wikiId = path28__default.basename(patch.frontmatter.target, ".md");
|
|
37579
37585
|
const currentEntry = await readWikiEntry(wikiId, paths);
|
|
37580
|
-
const currentPath =
|
|
37586
|
+
const currentPath = path28__default.join(paths.root, patch.frontmatter.target);
|
|
37581
37587
|
const currentMarkdown = await pathExists(currentPath) ? await readPatchFile(currentPath) : void 0;
|
|
37582
37588
|
if (meta3.baseVersion !== void 0 && currentEntry?.version !== meta3.baseVersion) {
|
|
37583
37589
|
throw new Error(
|
|
@@ -37636,17 +37642,17 @@ function assertCanonicalPatchTarget(target) {
|
|
|
37636
37642
|
if (target.endsWith("/")) {
|
|
37637
37643
|
throw new Error("patch target must not end with a slash");
|
|
37638
37644
|
}
|
|
37639
|
-
if (target.startsWith("/") ||
|
|
37645
|
+
if (target.startsWith("/") || path28__default.posix.isAbsolute(target) || path28__default.win32.isAbsolute(target)) {
|
|
37640
37646
|
throw new Error("patch target must be relative");
|
|
37641
37647
|
}
|
|
37642
|
-
if (
|
|
37648
|
+
if (path28__default.posix.normalize(target) !== target) {
|
|
37643
37649
|
throw new Error("patch target must not contain dot segments or redundant separators");
|
|
37644
37650
|
}
|
|
37645
37651
|
}
|
|
37646
37652
|
function canonicalApprovalLockKey(paths, target) {
|
|
37647
37653
|
const wikiRoot = realpathSync(paths.wikiDir);
|
|
37648
|
-
const relativeTarget =
|
|
37649
|
-
const targetPath =
|
|
37654
|
+
const relativeTarget = path28__default.posix.relative("wiki", target);
|
|
37655
|
+
const targetPath = path28__default.join(wikiRoot, ...relativeTarget.split("/"));
|
|
37650
37656
|
return `${wikiRoot}\0${targetPath}`.toLowerCase();
|
|
37651
37657
|
}
|
|
37652
37658
|
function canonicalPatchEditLockKey(paths, patchId) {
|
|
@@ -37662,7 +37668,7 @@ function assertNoSymlinkPathComponents(target, paths) {
|
|
|
37662
37668
|
throw error51;
|
|
37663
37669
|
}
|
|
37664
37670
|
for (const part of parts) {
|
|
37665
|
-
current =
|
|
37671
|
+
current = path28__default.join(current, part);
|
|
37666
37672
|
try {
|
|
37667
37673
|
if (lstatSync(current).isSymbolicLink()) {
|
|
37668
37674
|
throw new Error("patch target must not include symlink path components");
|
|
@@ -37677,8 +37683,8 @@ function assertSafeRawSourceRef(rawSourceRef, paths) {
|
|
|
37677
37683
|
if (!rawSourceRef.startsWith("raw/")) {
|
|
37678
37684
|
throw new Error("raw source provenance must point into raw/");
|
|
37679
37685
|
}
|
|
37680
|
-
const absoluteRef =
|
|
37681
|
-
if (!absoluteRef.startsWith(`${paths.rawDir}${
|
|
37686
|
+
const absoluteRef = path28__default.resolve(paths.root, rawSourceRef);
|
|
37687
|
+
if (!absoluteRef.startsWith(`${paths.rawDir}${path28__default.sep}`)) {
|
|
37682
37688
|
throw new Error("raw source provenance must point into raw/");
|
|
37683
37689
|
}
|
|
37684
37690
|
}
|
|
@@ -37694,14 +37700,14 @@ function classifyPatchConflict(error51) {
|
|
|
37694
37700
|
}
|
|
37695
37701
|
async function recordPatchConflict(patch, paths, reason, options) {
|
|
37696
37702
|
const now = /* @__PURE__ */ new Date();
|
|
37697
|
-
const targetPath =
|
|
37703
|
+
const targetPath = path28__default.join(paths.root, patch.frontmatter.target);
|
|
37698
37704
|
const current = await pathExists(targetPath) ? await readPatchFile(targetPath) : void 0;
|
|
37699
37705
|
const currentEntry = current ? parseStoredWikiEntry(current) : void 0;
|
|
37700
37706
|
const proposedEntry = parsePatchBodyEntry(patch.body);
|
|
37701
37707
|
const record2 = await createConflict({
|
|
37702
37708
|
reason,
|
|
37703
37709
|
target: patch.frontmatter.target,
|
|
37704
|
-
wikiId: proposedEntry?.id ??
|
|
37710
|
+
wikiId: proposedEntry?.id ?? path28__default.basename(patch.frontmatter.target, ".md"),
|
|
37705
37711
|
title: proposedEntry?.title,
|
|
37706
37712
|
proposer: patch.frontmatter.proposer,
|
|
37707
37713
|
rawSourceRef: options?.rawSourceRef,
|
|
@@ -37797,11 +37803,11 @@ function parseInlineArray(value) {
|
|
|
37797
37803
|
return inner.split(",").map((item) => item.trim().replace(/^"(.*)"$/, "$1"));
|
|
37798
37804
|
}
|
|
37799
37805
|
async function archiveQueueEntry(id, paths, meta3) {
|
|
37800
|
-
const fromDir =
|
|
37801
|
-
const toDir =
|
|
37806
|
+
const fromDir = path28__default.join(paths.queueDir, id);
|
|
37807
|
+
const toDir = path28__default.join(paths.archiveDir, id);
|
|
37802
37808
|
await removePath(toDir);
|
|
37803
37809
|
await movePath(fromDir, toDir);
|
|
37804
|
-
await writeJsonFile(
|
|
37810
|
+
await writeJsonFile(path28__default.join(toDir, PATCH_META_FILENAME), meta3, paths);
|
|
37805
37811
|
}
|
|
37806
37812
|
function buildQueueIdHelp(prefix, availableIds) {
|
|
37807
37813
|
if (availableIds.length === 0) {
|
|
@@ -38013,7 +38019,7 @@ async function resolveCompileSource(input, paths, now) {
|
|
|
38013
38019
|
}
|
|
38014
38020
|
async function buildCompileProposals(input, paths, now, resolvedSource) {
|
|
38015
38021
|
const sourceTarget = `wiki/sources/${resolvedSource.sourcePageId}.md`;
|
|
38016
|
-
const sourceExists = await pathExists(
|
|
38022
|
+
const sourceExists = await pathExists(path28__default.join(paths.root, sourceTarget));
|
|
38017
38023
|
const existingEntries = await listWiki(paths);
|
|
38018
38024
|
const sourcePageTitle = resolvedSource.sourceTitle?.trim() || `Source ${resolvedSource.sourcePageId}`;
|
|
38019
38025
|
const existingSourceEntry = existingEntries.find((entry) => entry.id === resolvedSource.sourcePageId);
|
|
@@ -38035,7 +38041,7 @@ async function buildCompileProposals(input, paths, now, resolvedSource) {
|
|
|
38035
38041
|
target: sourceTarget,
|
|
38036
38042
|
summary: truncateSummary(`Compile source page ${sourcePageTitle}`),
|
|
38037
38043
|
entry: sourceEntry,
|
|
38038
|
-
baseHash: sourceExists ? computeContentHash(await readPatchFile(
|
|
38044
|
+
baseHash: sourceExists ? computeContentHash(await readPatchFile(path28__default.join(paths.root, sourceTarget))) : void 0,
|
|
38039
38045
|
baseVersion: existingSourceEntry?.version
|
|
38040
38046
|
}];
|
|
38041
38047
|
const relatedCandidates = await discoverRelatedEntryCandidates(paths, resolvedSource.sourceContent, resolvedSource.sourceTitle);
|
|
@@ -38055,7 +38061,7 @@ async function buildCompileProposals(input, paths, now, resolvedSource) {
|
|
|
38055
38061
|
rawSourceRefs: mergeRawSourceRefs(existing.rawSourceRefs, existing.rawSourceRef, { ref: resolvedSource.rawSourceRef }),
|
|
38056
38062
|
body: appendSourceCompileNote(existing.body, resolvedSource.sourcePageId, resolvedSource.rawSourceRef)
|
|
38057
38063
|
},
|
|
38058
|
-
baseHash: computeContentHash(await readPatchFile(
|
|
38064
|
+
baseHash: computeContentHash(await readPatchFile(path28__default.join(paths.wikiDir, `${existing.id}.md`))),
|
|
38059
38065
|
baseVersion: existing.version
|
|
38060
38066
|
});
|
|
38061
38067
|
}
|
|
@@ -38190,13 +38196,13 @@ async function readClaims(entryId, paths) {
|
|
|
38190
38196
|
}
|
|
38191
38197
|
}
|
|
38192
38198
|
function getClaimsDir(paths) {
|
|
38193
|
-
return
|
|
38199
|
+
return path28__default.join(paths.wikiDir, CLAIMS_DIRNAME);
|
|
38194
38200
|
}
|
|
38195
38201
|
function getClaimsFile(paths, entryId) {
|
|
38196
38202
|
assertSafeEntryId(entryId);
|
|
38197
|
-
const claimsFile =
|
|
38198
|
-
const relative =
|
|
38199
|
-
if (!relative || relative.startsWith("..") ||
|
|
38203
|
+
const claimsFile = path28__default.join(getClaimsDir(paths), `${entryId}.json`);
|
|
38204
|
+
const relative = path28__default.relative(getClaimsDir(paths), claimsFile);
|
|
38205
|
+
if (!relative || relative.startsWith("..") || path28__default.isAbsolute(relative)) {
|
|
38200
38206
|
throw new Error(`[fleet-wiki] claims sidecar escapes wiki/.claims: ${entryId}`);
|
|
38201
38207
|
}
|
|
38202
38208
|
return claimsFile;
|
|
@@ -38287,7 +38293,7 @@ function assertSafeClaimRawRef(ref) {
|
|
|
38287
38293
|
if (!ref.startsWith("raw/")) {
|
|
38288
38294
|
throw new Error(`claim sourceRef must point into raw/: ${ref}`);
|
|
38289
38295
|
}
|
|
38290
|
-
if (ref.includes("..") ||
|
|
38296
|
+
if (ref.includes("..") || path28__default.isAbsolute(ref)) {
|
|
38291
38297
|
throw new Error(`claim sourceRef escapes raw/: ${ref}`);
|
|
38292
38298
|
}
|
|
38293
38299
|
}
|
|
@@ -38365,22 +38371,22 @@ async function runDryDock(paths, options = {}) {
|
|
|
38365
38371
|
}
|
|
38366
38372
|
for (const fileName of await listFileNames(paths.rawDir)) {
|
|
38367
38373
|
if (!fileName.endsWith(".md")) continue;
|
|
38368
|
-
const filePath =
|
|
38374
|
+
const filePath = path28__default.join(paths.rawDir, fileName);
|
|
38369
38375
|
issues.push(...safetyIssues(await readPatchFile(filePath), filePath));
|
|
38370
38376
|
}
|
|
38371
38377
|
for (const queueId of await listDirectoryNames(paths.queueDir)) {
|
|
38372
38378
|
if (queueId === PATCH_SET_DIRNAME) continue;
|
|
38373
|
-
const queueDir =
|
|
38379
|
+
const queueDir = path28__default.join(paths.queueDir, queueId);
|
|
38374
38380
|
try {
|
|
38375
|
-
const patchContent = await readPatchFile(
|
|
38376
|
-
issues.push(...safetyIssues(patchContent,
|
|
38377
|
-
await readJsonFile2(
|
|
38381
|
+
const patchContent = await readPatchFile(path28__default.join(queueDir, PATCH_FILENAME));
|
|
38382
|
+
issues.push(...safetyIssues(patchContent, path28__default.join(queueDir, PATCH_FILENAME)));
|
|
38383
|
+
await readJsonFile2(path28__default.join(queueDir, PATCH_META_FILENAME));
|
|
38378
38384
|
} catch {
|
|
38379
38385
|
issues.push(issue2("malformed_queue", "error", "\uC190\uC0C1\uB41C queue \uC5D4\uD2B8\uB9AC", queueDir));
|
|
38380
38386
|
}
|
|
38381
38387
|
}
|
|
38382
|
-
for (const patchSetId of await listDirectoryNames(
|
|
38383
|
-
const patchSetMetaFile =
|
|
38388
|
+
for (const patchSetId of await listDirectoryNames(path28__default.join(paths.queueDir, PATCH_SET_DIRNAME))) {
|
|
38389
|
+
const patchSetMetaFile = path28__default.join(paths.queueDir, PATCH_SET_DIRNAME, patchSetId, PATCH_META_FILENAME);
|
|
38384
38390
|
let patchSet;
|
|
38385
38391
|
try {
|
|
38386
38392
|
patchSet = await readPatchSet(paths, patchSetId);
|
|
@@ -38389,8 +38395,8 @@ async function runDryDock(paths, options = {}) {
|
|
|
38389
38395
|
continue;
|
|
38390
38396
|
}
|
|
38391
38397
|
for (const patchId of patchSet.patchIds) {
|
|
38392
|
-
const queueMetaFile =
|
|
38393
|
-
const archiveMetaFile =
|
|
38398
|
+
const queueMetaFile = path28__default.join(paths.queueDir, patchId, PATCH_META_FILENAME);
|
|
38399
|
+
const archiveMetaFile = path28__default.join(paths.archiveDir, patchId, PATCH_META_FILENAME);
|
|
38394
38400
|
if (!await pathExists(queueMetaFile) && !await pathExists(archiveMetaFile)) {
|
|
38395
38401
|
issues.push(
|
|
38396
38402
|
issue2(
|
|
@@ -38427,7 +38433,7 @@ async function runDryDock(paths, options = {}) {
|
|
|
38427
38433
|
"conflict_unresolved",
|
|
38428
38434
|
"warning",
|
|
38429
38435
|
`\uBBF8\uD574\uACB0 conflict: ${conflict.reason} (${conflict.target})`,
|
|
38430
|
-
|
|
38436
|
+
path28__default.join(paths.conflictsDir, conflict.id, "meta.json")
|
|
38431
38437
|
)
|
|
38432
38438
|
);
|
|
38433
38439
|
}
|
|
@@ -38440,7 +38446,7 @@ async function runDryDock(paths, options = {}) {
|
|
|
38440
38446
|
"unresolved_conflict",
|
|
38441
38447
|
"warning",
|
|
38442
38448
|
"\uC190\uC0C1\uB41C conflict \uC5D4\uD2B8\uB9AC",
|
|
38443
|
-
|
|
38449
|
+
path28__default.join(paths.conflictsDir, conflictId, "meta.json")
|
|
38444
38450
|
)
|
|
38445
38451
|
);
|
|
38446
38452
|
}
|
|
@@ -38497,8 +38503,8 @@ async function claimIssues(paths, wikiIds) {
|
|
|
38497
38503
|
const claimsDir = getClaimsDir(paths);
|
|
38498
38504
|
for (const fileName of await listFileNames(claimsDir)) {
|
|
38499
38505
|
if (!fileName.endsWith(".json")) continue;
|
|
38500
|
-
const filePath =
|
|
38501
|
-
const entryIdFromFile =
|
|
38506
|
+
const filePath = path28__default.join(claimsDir, fileName);
|
|
38507
|
+
const entryIdFromFile = path28__default.basename(fileName, ".json");
|
|
38502
38508
|
let raw;
|
|
38503
38509
|
try {
|
|
38504
38510
|
raw = await readJsonFile2(filePath);
|
|
@@ -38577,7 +38583,7 @@ function toSemanticEntry(filePath, frontmatter, body) {
|
|
|
38577
38583
|
async function schemaIssues(paths) {
|
|
38578
38584
|
const issues = [];
|
|
38579
38585
|
const schema = await readWorkspaceSchemaSummary(paths);
|
|
38580
|
-
const agentsPath =
|
|
38586
|
+
const agentsPath = path28__default.join(paths.schemaDir, WORKSPACE_SCHEMA_AGENTS_FILENAME);
|
|
38581
38587
|
if (!await pathExists(schema.wikiSchemaPath)) {
|
|
38582
38588
|
issues.push(issue2("schema_missing", "warning", `Workspace schema file is missing: schema/${WORKSPACE_SCHEMA_FILENAME}`, schema.wikiSchemaPath));
|
|
38583
38589
|
} else {
|
|
@@ -38964,7 +38970,7 @@ async function listWikiMarkdownFiles(dirPath) {
|
|
|
38964
38970
|
const files = [];
|
|
38965
38971
|
const sortedEntries = entries.sort((left, right) => left.name.localeCompare(right.name));
|
|
38966
38972
|
for (const entry of sortedEntries) {
|
|
38967
|
-
const filePath =
|
|
38973
|
+
const filePath = path28__default.join(dirPath, entry.name);
|
|
38968
38974
|
if (entry.isDirectory()) {
|
|
38969
38975
|
files.push(...await listWikiMarkdownFiles(filePath));
|
|
38970
38976
|
continue;
|
|
@@ -39048,7 +39054,7 @@ async function planIngest(input, paths, now) {
|
|
|
39048
39054
|
const target = `wiki/${input.id}.md`;
|
|
39049
39055
|
const proposer = input.proposer ?? "tool:wiki_ingest";
|
|
39050
39056
|
const currentEntry = await readWikiEntry(input.id, paths);
|
|
39051
|
-
const currentMarkdown = currentEntry ? await readPatchFile(
|
|
39057
|
+
const currentMarkdown = currentEntry ? await readPatchFile(path28__default.join(paths.wikiDir, `${input.id}.md`)) : void 0;
|
|
39052
39058
|
const currentHash = currentMarkdown ? computeContentHash(currentMarkdown) : void 0;
|
|
39053
39059
|
const rawSource = buildRawSourceEntry(input, now);
|
|
39054
39060
|
await ensureWorkspaceSchema(paths);
|
|
@@ -39727,11 +39733,11 @@ async function editQueuedPatch(input, paths) {
|
|
|
39727
39733
|
};
|
|
39728
39734
|
}
|
|
39729
39735
|
async function readQueuedPatchSnapshot(paths, patchId) {
|
|
39730
|
-
const queueDir =
|
|
39731
|
-
const markdown = await readPatchFile(
|
|
39736
|
+
const queueDir = path28__default.join(paths.queueDir, patchId);
|
|
39737
|
+
const markdown = await readPatchFile(path28__default.join(queueDir, PATCH_FILENAME));
|
|
39732
39738
|
return {
|
|
39733
39739
|
patch: await parsePatch(markdown),
|
|
39734
|
-
meta: await readJsonFile2(
|
|
39740
|
+
meta: await readJsonFile2(path28__default.join(queueDir, PATCH_META_FILENAME)),
|
|
39735
39741
|
patchHash: computeContentHash(markdown)
|
|
39736
39742
|
};
|
|
39737
39743
|
}
|
|
@@ -40493,7 +40499,7 @@ ${input.answer ?? ""}`)}`;
|
|
|
40493
40499
|
assertSafeEntryId(targetId);
|
|
40494
40500
|
const subdir = input.targetType === "synthesis" ? "synthesis" : "queries";
|
|
40495
40501
|
const target = `wiki/${subdir}/${targetId}.md`;
|
|
40496
|
-
const absoluteTarget =
|
|
40502
|
+
const absoluteTarget = path28__default.join(paths.root, target);
|
|
40497
40503
|
const exists = await pathExists(absoluteTarget);
|
|
40498
40504
|
const existingEntry = exists ? await readWikiEntry(targetId, paths) : null;
|
|
40499
40505
|
if (exists && !existingEntry) {
|
|
@@ -40575,7 +40581,7 @@ function assertSafeRawRef(rawRef) {
|
|
|
40575
40581
|
if (!rawRef.startsWith("raw/")) {
|
|
40576
40582
|
throw new Error(`[fleet-wiki] wiki_query raw source ref must point into raw/: ${rawRef}`);
|
|
40577
40583
|
}
|
|
40578
|
-
if (rawRef.includes("..") ||
|
|
40584
|
+
if (rawRef.includes("..") || path28__default.isAbsolute(rawRef)) {
|
|
40579
40585
|
throw new Error(`[fleet-wiki] wiki_query raw source ref escapes raw/: ${rawRef}`);
|
|
40580
40586
|
}
|
|
40581
40587
|
}
|
|
@@ -40694,7 +40700,7 @@ async function buildReadEntryResult(entry, paths, graph, input) {
|
|
|
40694
40700
|
rawSourceRef: entry.rawSourceRef,
|
|
40695
40701
|
rawSourceRefs,
|
|
40696
40702
|
source: {
|
|
40697
|
-
path:
|
|
40703
|
+
path: path28__default.join("wiki", `${entry.id}.md`),
|
|
40698
40704
|
rawSourceRef: entry.rawSourceRef,
|
|
40699
40705
|
rawSourceRefs
|
|
40700
40706
|
},
|
|
@@ -40820,7 +40826,7 @@ function buildRelatedEntries(entry, graph) {
|
|
|
40820
40826
|
deduped.set(candidate.id, {
|
|
40821
40827
|
id: relatedEntry.id,
|
|
40822
40828
|
title: relatedEntry.title,
|
|
40823
|
-
path:
|
|
40829
|
+
path: path28__default.join("wiki", `${relatedEntry.id}.md`),
|
|
40824
40830
|
reason: candidate.reason
|
|
40825
40831
|
});
|
|
40826
40832
|
}
|
|
@@ -41120,9 +41126,58 @@ function createPluginTerminalTicketRegistry(deps = {}) {
|
|
|
41120
41126
|
}
|
|
41121
41127
|
return { ttlMs, issue: issue3, consume, prune };
|
|
41122
41128
|
}
|
|
41129
|
+
var FLEET_CONSOLE_PACKAGE_NAME = "@dotobokuri/fleet-console";
|
|
41130
|
+
function resolveConsolePackageRequire(currentFile, fallback) {
|
|
41131
|
+
return findConsolePackageRequire(currentFile) ?? fallback;
|
|
41132
|
+
}
|
|
41133
|
+
function findConsolePackageRequire(currentFile) {
|
|
41134
|
+
const explicitRoot = process.env.FLEET_CONSOLE_PACKAGE_ROOT;
|
|
41135
|
+
if (explicitRoot) {
|
|
41136
|
+
const explicitPackageJson = path28__default.join(explicitRoot, "package.json");
|
|
41137
|
+
if (isFleetConsolePackage(explicitPackageJson)) return createRequire(explicitPackageJson);
|
|
41138
|
+
}
|
|
41139
|
+
let dir = path28__default.dirname(currentFile);
|
|
41140
|
+
while (true) {
|
|
41141
|
+
const packageJson = path28__default.join(dir, "package.json");
|
|
41142
|
+
if (isFleetConsolePackage(packageJson)) return createRequire(packageJson);
|
|
41143
|
+
const nestedConsolePackage = path28__default.join(dir, "runtime", "fleet-console", "package.json");
|
|
41144
|
+
if (isFleetConsolePackage(nestedConsolePackage)) return createRequire(nestedConsolePackage);
|
|
41145
|
+
const siblingConsolePackage = path28__default.join(dir, "..", "..", "fleet-console", "package.json");
|
|
41146
|
+
if (isFleetConsolePackage(siblingConsolePackage)) return createRequire(siblingConsolePackage);
|
|
41147
|
+
const parent = path28__default.dirname(dir);
|
|
41148
|
+
if (parent === dir) return null;
|
|
41149
|
+
dir = parent;
|
|
41150
|
+
}
|
|
41151
|
+
}
|
|
41152
|
+
function isFleetConsolePackage(packageJson) {
|
|
41153
|
+
if (!existsSync(packageJson)) return false;
|
|
41154
|
+
try {
|
|
41155
|
+
const manifest = JSON.parse(readFileSync(packageJson, "utf8"));
|
|
41156
|
+
return manifest.name === FLEET_CONSOLE_PACKAGE_NAME;
|
|
41157
|
+
} catch {
|
|
41158
|
+
return false;
|
|
41159
|
+
}
|
|
41160
|
+
}
|
|
41161
|
+
|
|
41162
|
+
// ../fleet-plugins/terminal/server/shared/launch-env.ts
|
|
41163
|
+
var CONSOLE_INTERNAL_ENV_KEYS = [
|
|
41164
|
+
"FLEET_CONSOLE_OWNER_ID",
|
|
41165
|
+
"FLEET_CONSOLE_OWNER_KIND",
|
|
41166
|
+
"FLEET_CONSOLE_PROTOCOL_VERSION",
|
|
41167
|
+
"FLEET_CONSOLE_RESOURCE_ROOT",
|
|
41168
|
+
"FLEET_CONSOLE_DESKTOP_DEVELOPMENT",
|
|
41169
|
+
"FLEET_CONSOLE_DESKTOP_VERSION",
|
|
41170
|
+
"FLEET_CONSOLE_PACKAGE_ROOT"
|
|
41171
|
+
];
|
|
41172
|
+
function stripConsoleInternalEnv(env) {
|
|
41173
|
+
const next = { ...env };
|
|
41174
|
+
for (const key of CONSOLE_INTERNAL_ENV_KEYS) delete next[key];
|
|
41175
|
+
return next;
|
|
41176
|
+
}
|
|
41177
|
+
|
|
41178
|
+
// ../fleet-plugins/terminal/server/shared/pty.ts
|
|
41123
41179
|
var DEFAULT_TERMINAL_CWD_FALLBACK = os3__default.homedir;
|
|
41124
41180
|
var TERMINAL_TERM = "xterm-256color";
|
|
41125
|
-
var FLEET_CONSOLE_PACKAGE_NAME = "@dotobokuri/fleet-console";
|
|
41126
41181
|
var require2 = createRequire(import.meta.url);
|
|
41127
41182
|
function createShellTerminalLaunchResolver(deps = {}) {
|
|
41128
41183
|
const baseCwd = deps.cwd ?? process5.cwd();
|
|
@@ -41158,31 +41213,7 @@ function loadNodePty() {
|
|
|
41158
41213
|
return loadNodePtyRequire(fileURLToPath(import.meta.url))("node-pty");
|
|
41159
41214
|
}
|
|
41160
41215
|
function loadNodePtyRequire(currentFile) {
|
|
41161
|
-
|
|
41162
|
-
return consolePackageRequire ?? require2;
|
|
41163
|
-
}
|
|
41164
|
-
function findConsolePackageRequire(currentFile) {
|
|
41165
|
-
let dir = path27__default.dirname(currentFile);
|
|
41166
|
-
while (true) {
|
|
41167
|
-
const packageJson = path27__default.join(dir, "package.json");
|
|
41168
|
-
if (isFleetConsolePackage(packageJson)) return createRequire(packageJson);
|
|
41169
|
-
const nestedConsolePackage = path27__default.join(dir, "runtime", "fleet-console", "package.json");
|
|
41170
|
-
if (isFleetConsolePackage(nestedConsolePackage)) return createRequire(nestedConsolePackage);
|
|
41171
|
-
const siblingConsolePackage = path27__default.join(dir, "..", "..", "fleet-console", "package.json");
|
|
41172
|
-
if (isFleetConsolePackage(siblingConsolePackage)) return createRequire(siblingConsolePackage);
|
|
41173
|
-
const parent = path27__default.dirname(dir);
|
|
41174
|
-
if (parent === dir) return null;
|
|
41175
|
-
dir = parent;
|
|
41176
|
-
}
|
|
41177
|
-
}
|
|
41178
|
-
function isFleetConsolePackage(packageJson) {
|
|
41179
|
-
if (!existsSync(packageJson)) return false;
|
|
41180
|
-
try {
|
|
41181
|
-
const manifest = JSON.parse(readFileSync(packageJson, "utf8"));
|
|
41182
|
-
return manifest.name === FLEET_CONSOLE_PACKAGE_NAME;
|
|
41183
|
-
} catch {
|
|
41184
|
-
return false;
|
|
41185
|
-
}
|
|
41216
|
+
return resolveConsolePackageRequire(currentFile, require2);
|
|
41186
41217
|
}
|
|
41187
41218
|
function resolveUserShell(env, platform) {
|
|
41188
41219
|
if (env.SHELL) return env.SHELL;
|
|
@@ -41201,7 +41232,7 @@ function resolveWindowsLaunchBinary(bin, args, env, platform, label) {
|
|
|
41201
41232
|
}
|
|
41202
41233
|
function buildShellLaunchEnv(env) {
|
|
41203
41234
|
return {
|
|
41204
|
-
...env,
|
|
41235
|
+
...stripConsoleInternalEnv(env),
|
|
41205
41236
|
TERM: TERMINAL_TERM
|
|
41206
41237
|
};
|
|
41207
41238
|
}
|
|
@@ -41542,7 +41573,7 @@ function isResizeFrame(value) {
|
|
|
41542
41573
|
const rows = frame.rows;
|
|
41543
41574
|
return frame.type === "resize" && typeof cols === "number" && typeof rows === "number" && Number.isInteger(cols) && Number.isInteger(rows) && cols > 0 && rows > 0;
|
|
41544
41575
|
}
|
|
41545
|
-
var require3 = createRequire(import.meta.url);
|
|
41576
|
+
var require3 = resolveConsolePackageRequire(fileURLToPath(import.meta.url), createRequire(import.meta.url));
|
|
41546
41577
|
function createPluginTerminalUpgradeHandler(deps) {
|
|
41547
41578
|
let wsServer = null;
|
|
41548
41579
|
const handleUpgrade = ({ req, socket, head }) => {
|
|
@@ -41955,7 +41986,7 @@ function captureSession(options) {
|
|
|
41955
41986
|
function readProviderSessionCapture(fleetSessionId, deps = {}) {
|
|
41956
41987
|
if (!isSafeCaptureId(fleetSessionId)) return null;
|
|
41957
41988
|
const capturesDir = deps.capturesDir ?? defaultCapturePaths().capturesDir;
|
|
41958
|
-
const filePath =
|
|
41989
|
+
const filePath = path28__default.join(capturesDir, `${fleetSessionId}.json`);
|
|
41959
41990
|
try {
|
|
41960
41991
|
const parsed = JSON.parse(fs2__default.readFileSync(filePath, "utf8"));
|
|
41961
41992
|
return sanitizeProviderSession(parsed);
|
|
@@ -41967,7 +41998,7 @@ function unlinkProviderSessionCapture(fleetSessionId, deps = {}) {
|
|
|
41967
41998
|
if (!isSafeCaptureId(fleetSessionId)) return false;
|
|
41968
41999
|
const capturesDir = deps.capturesDir ?? defaultCapturePaths().capturesDir;
|
|
41969
42000
|
try {
|
|
41970
|
-
fs2__default.unlinkSync(
|
|
42001
|
+
fs2__default.unlinkSync(path28__default.join(capturesDir, `${fleetSessionId}.json`));
|
|
41971
42002
|
return true;
|
|
41972
42003
|
} catch {
|
|
41973
42004
|
return false;
|
|
@@ -41979,8 +42010,8 @@ function captureSessionStrict(options) {
|
|
|
41979
42010
|
const input = parseHookInput(options.input ?? "");
|
|
41980
42011
|
const providerSession = toProviderSession(provider, input, options.now ?? (() => /* @__PURE__ */ new Date()));
|
|
41981
42012
|
const capturesDir = (options.paths ?? defaultCapturePaths()).capturesDir;
|
|
41982
|
-
const finalPath =
|
|
41983
|
-
const tempPath =
|
|
42013
|
+
const finalPath = path28__default.join(capturesDir, `${fleetSessionId}.json`);
|
|
42014
|
+
const tempPath = path28__default.join(capturesDir, `${CAPTURE_TEMP_PREFIX}${fleetSessionId}.${process5.pid}.${Date.now()}.tmp`);
|
|
41984
42015
|
fs2__default.mkdirSync(capturesDir, { recursive: true, mode: 448 });
|
|
41985
42016
|
fs2__default.writeFileSync(tempPath, `${JSON.stringify(providerSession, null, 2)}
|
|
41986
42017
|
`, { mode: 384 });
|
|
@@ -41994,7 +42025,7 @@ function parseProvider(value) {
|
|
|
41994
42025
|
function readFleetSessionId(env) {
|
|
41995
42026
|
const value = env.FLEET_CONSOLE_SESSION_ID;
|
|
41996
42027
|
if (!value) throw new Error("missing_fleet_session_id");
|
|
41997
|
-
if (
|
|
42028
|
+
if (path28__default.basename(value) !== value || value.includes(path28__default.sep) || value.includes(path28__default.posix.sep)) {
|
|
41998
42029
|
throw new Error("invalid_fleet_session_id");
|
|
41999
42030
|
}
|
|
42000
42031
|
return value;
|
|
@@ -42039,10 +42070,10 @@ function isProvider(value) {
|
|
|
42039
42070
|
return value === "claude" || value === "codex" || value === "cursor";
|
|
42040
42071
|
}
|
|
42041
42072
|
function isSafeCaptureId(value) {
|
|
42042
|
-
return value.length > 0 &&
|
|
42073
|
+
return value.length > 0 && path28__default.basename(value) === value && !value.includes(path28__default.sep) && !value.includes(path28__default.posix.sep);
|
|
42043
42074
|
}
|
|
42044
42075
|
function defaultCapturePaths() {
|
|
42045
|
-
return { capturesDir:
|
|
42076
|
+
return { capturesDir: path28__default.join(getFleetDataDir(), CONSOLE_DATA_DIR_NAME, CONSOLE_CAPTURES_DIR_NAME) };
|
|
42046
42077
|
}
|
|
42047
42078
|
var JAVASCRIPT_ENTRY_EXTENSIONS = /* @__PURE__ */ new Set([".cjs", ".js", ".mjs"]);
|
|
42048
42079
|
var TYPESCRIPT_ENTRY_EXTENSIONS = /* @__PURE__ */ new Set([".cts", ".mts", ".ts", ".tsx"]);
|
|
@@ -42057,7 +42088,7 @@ function buildConsoleAutoNameHookCommand(entry) {
|
|
|
42057
42088
|
return buildConsoleCliHookExec(entry, ["hook", "auto-name"]);
|
|
42058
42089
|
}
|
|
42059
42090
|
function buildConsoleCaptureHookCommand(entry, cliId) {
|
|
42060
|
-
const extension =
|
|
42091
|
+
const extension = path28__default.extname(entry.entryPath);
|
|
42061
42092
|
if (JAVASCRIPT_ENTRY_EXTENSIONS.has(extension)) {
|
|
42062
42093
|
return createSessionCaptureHookExec({
|
|
42063
42094
|
entryPath: entry.entryPath,
|
|
@@ -42093,11 +42124,11 @@ function runCodexCommand(command) {
|
|
|
42093
42124
|
}
|
|
42094
42125
|
function withConsoleMarketplaceLock(target, fn) {
|
|
42095
42126
|
const lockDir = `${target}${MARKETPLACE_LOCK_DIR_SUFFIX}`;
|
|
42096
|
-
mkdirSync(
|
|
42127
|
+
mkdirSync(path28__default.dirname(lockDir), { recursive: true });
|
|
42097
42128
|
return withDirectoryLock({ lockDir }, fn);
|
|
42098
42129
|
}
|
|
42099
42130
|
function buildConsoleCliHookExec(entry, trailingArgs) {
|
|
42100
|
-
const extension =
|
|
42131
|
+
const extension = path28__default.extname(entry.entryPath);
|
|
42101
42132
|
if (JAVASCRIPT_ENTRY_EXTENSIONS.has(extension)) {
|
|
42102
42133
|
return {
|
|
42103
42134
|
command: entry.execPath,
|
|
@@ -42181,7 +42212,7 @@ function resolveHookEntryPath(candidate) {
|
|
|
42181
42212
|
return CONSOLE_ENTRY_PATH;
|
|
42182
42213
|
}
|
|
42183
42214
|
function hasHookEntryExtension(entryPath) {
|
|
42184
|
-
return HOOK_ENTRY_EXTENSIONS.has(
|
|
42215
|
+
return HOOK_ENTRY_EXTENSIONS.has(path28__default.extname(entryPath));
|
|
42185
42216
|
}
|
|
42186
42217
|
async function createAgentCliLaunchSpec(options) {
|
|
42187
42218
|
const cleanupStack = [];
|
|
@@ -42275,7 +42306,7 @@ function parseTerminalCommand(command) {
|
|
|
42275
42306
|
}
|
|
42276
42307
|
function buildLaunchEnv(env, cwd, sessionId) {
|
|
42277
42308
|
return {
|
|
42278
|
-
...env,
|
|
42309
|
+
...stripConsoleInternalEnv(env),
|
|
42279
42310
|
...sessionId ? { FLEET_CONSOLE_SESSION_ID: sessionId, INIT_CWD: cwd, PWD: cwd } : {},
|
|
42280
42311
|
TERM: TERMINAL_TERM2
|
|
42281
42312
|
};
|
|
@@ -42403,7 +42434,7 @@ function createConsoleObservabilityStore(deps = {}) {
|
|
|
42403
42434
|
return terminalSessionsById.get(sessionId)?.cwd ?? workspacesByCliRunId.get(sessionId)?.session.cwd ?? null;
|
|
42404
42435
|
}
|
|
42405
42436
|
function createPendingTerminalSession(input) {
|
|
42406
|
-
if (!
|
|
42437
|
+
if (!path28__default.isAbsolute(input.cwd)) throw new Error("Terminal session cwd must be absolute");
|
|
42407
42438
|
const createdAt = input.createdAt ?? now();
|
|
42408
42439
|
const canonicalCwd = canonicalizeTheaterPath(input.cwd);
|
|
42409
42440
|
const theaterId = workspaceHash(canonicalCwd);
|
|
@@ -42411,7 +42442,7 @@ function createConsoleObservabilityStore(deps = {}) {
|
|
|
42411
42442
|
sessionId: input.sessionId,
|
|
42412
42443
|
cwd: input.cwd,
|
|
42413
42444
|
canonicalCwd,
|
|
42414
|
-
cwdLabel:
|
|
42445
|
+
cwdLabel: path28__default.basename(input.cwd) || input.cwd,
|
|
42415
42446
|
cliId: input.cliId,
|
|
42416
42447
|
createdAt,
|
|
42417
42448
|
theaterId,
|
|
@@ -42426,7 +42457,7 @@ function createConsoleObservabilityStore(deps = {}) {
|
|
|
42426
42457
|
sessionId: operation.sessionId,
|
|
42427
42458
|
cwd: operation.cwd,
|
|
42428
42459
|
canonicalCwd: canonicalizeTheaterPath(operation.cwd),
|
|
42429
|
-
cwdLabel:
|
|
42460
|
+
cwdLabel: path28__default.basename(operation.cwd) || operation.cwd,
|
|
42430
42461
|
label: operation.label,
|
|
42431
42462
|
labelSource: operation.labelSource,
|
|
42432
42463
|
cliId: operation.cliId,
|
|
@@ -42506,13 +42537,15 @@ function createConsoleObservabilityStore(deps = {}) {
|
|
|
42506
42537
|
const session = terminalSessionsById.get(sessionId);
|
|
42507
42538
|
if (!session) return null;
|
|
42508
42539
|
const effectiveSource = session.labelSource ?? (session.label ? "user" : void 0);
|
|
42509
|
-
if (effectiveSource === "user") {
|
|
42540
|
+
if (effectiveSource === "user" || session.autoNamePromptSeen) {
|
|
42510
42541
|
return { session: toTerminalSessionInfo(session), renamed: false };
|
|
42511
42542
|
}
|
|
42512
42543
|
const next = label?.trim().slice(0, 200) ?? "";
|
|
42513
|
-
if (next.length === 0
|
|
42544
|
+
if (next.length === 0) {
|
|
42514
42545
|
return { session: toTerminalSessionInfo(session), renamed: false };
|
|
42515
42546
|
}
|
|
42547
|
+
session.autoNamePromptSeen = true;
|
|
42548
|
+
if (next === session.label) return { session: toTerminalSessionInfo(session), renamed: false };
|
|
42516
42549
|
session.label = next;
|
|
42517
42550
|
session.labelSource = "auto";
|
|
42518
42551
|
return { session: toTerminalSessionInfo(session), renamed: true };
|
|
@@ -42653,7 +42686,7 @@ function defaultWorkspaceHash(canonicalCwd) {
|
|
|
42653
42686
|
return crypto4.createHash("sha256").update(canonicalCwd).digest("hex").slice(0, 12);
|
|
42654
42687
|
}
|
|
42655
42688
|
function defaultCanonicalizeTheaterPath(cwd) {
|
|
42656
|
-
const resolved =
|
|
42689
|
+
const resolved = path28__default.resolve(cwd);
|
|
42657
42690
|
try {
|
|
42658
42691
|
return fs2__default.realpathSync.native(resolved);
|
|
42659
42692
|
} catch {
|
|
@@ -42893,6 +42926,7 @@ function buildAgentLaunchKindBackfillPatch(operation) {
|
|
|
42893
42926
|
}
|
|
42894
42927
|
function createAgentApi(ctx, terminalRuntime, deps) {
|
|
42895
42928
|
const runtime = createFleetAgentRuntimeLifecycle({
|
|
42929
|
+
globalOptionsService: deps.globalOptionsService,
|
|
42896
42930
|
onMcpServerStartError: (error51) => {
|
|
42897
42931
|
console.error("[fleet-console] Failed to start MCP server", error51);
|
|
42898
42932
|
},
|
|
@@ -42947,23 +42981,23 @@ function createAgentApi(ctx, terminalRuntime, deps) {
|
|
|
42947
42981
|
backfillAgentOperationLaunchKinds();
|
|
42948
42982
|
rehydrateDormantAgentOperations();
|
|
42949
42983
|
async function handle({ req, res, pathname }) {
|
|
42950
|
-
const
|
|
42951
|
-
if (
|
|
42984
|
+
const path43 = pathname.slice(`${ctx.basePath}/agent`.length) || "/";
|
|
42985
|
+
if (path43 === "/state") {
|
|
42952
42986
|
if (req.method !== "GET") return methodNotAllowed(res);
|
|
42953
42987
|
ctx.host.http.writeJson(res, 200, { agentClis: await buildAgentCliLaunchMetadata() });
|
|
42954
42988
|
return true;
|
|
42955
42989
|
}
|
|
42956
|
-
if (
|
|
42990
|
+
if (path43 === "/agent-cli/state") {
|
|
42957
42991
|
if (req.method !== "GET") return methodNotAllowed(res);
|
|
42958
42992
|
ctx.host.http.writeJson(res, 200, { clis: await detector.detect() });
|
|
42959
42993
|
return true;
|
|
42960
42994
|
}
|
|
42961
|
-
if (
|
|
42995
|
+
if (path43 === "/tenants") {
|
|
42962
42996
|
if (req.method !== "GET") return methodNotAllowed(res);
|
|
42963
42997
|
ctx.host.http.writeJson(res, 200, { tenants: observability.listWorkspaces() });
|
|
42964
42998
|
return true;
|
|
42965
42999
|
}
|
|
42966
|
-
if (
|
|
43000
|
+
if (path43 === "/jobs") {
|
|
42967
43001
|
if (req.method !== "GET") return methodNotAllowed(res);
|
|
42968
43002
|
const requestedTenantId = new URL(req.url ?? "/", "http://127.0.0.1").searchParams.get("tenant");
|
|
42969
43003
|
const visible = requestedTenantId ? observability.listWorkspaces().filter((workspace) => workspace.tenantId === requestedTenantId) : observability.listWorkspaces();
|
|
@@ -42974,7 +43008,7 @@ function createAgentApi(ctx, terminalRuntime, deps) {
|
|
|
42974
43008
|
ctx.host.http.writeJson(res, 200, { tenants: visible.map((workspace) => ({ tenantId: workspace.tenantId, tenantLabel: workspace.tenantLabel, jobs: observability.listJobs(workspace.tenantId), truncation: observability.getTruncation(workspace.tenantId) })) });
|
|
42975
43009
|
return true;
|
|
42976
43010
|
}
|
|
42977
|
-
if (
|
|
43011
|
+
if (path43 === "/events") {
|
|
42978
43012
|
if (req.method !== "GET") return methodNotAllowed(res);
|
|
42979
43013
|
const requestedTenantId = new URL(req.url ?? "/", "http://127.0.0.1").searchParams.get("tenant");
|
|
42980
43014
|
const visible = requestedTenantId ? observability.listWorkspaces().filter((workspace) => workspace.tenantId === requestedTenantId) : observability.listWorkspaces();
|
|
@@ -42985,11 +43019,11 @@ function createAgentApi(ctx, terminalRuntime, deps) {
|
|
|
42985
43019
|
writeAggregateObserverEvents(req, res, visible, observability, (tenantId) => observability.getWorkspace(tenantId), { subscribeAll: true });
|
|
42986
43020
|
return true;
|
|
42987
43021
|
}
|
|
42988
|
-
if (
|
|
42989
|
-
if (
|
|
42990
|
-
const sessionMatch =
|
|
43022
|
+
if (path43 === "/sessions") return handleSessions(req, res);
|
|
43023
|
+
if (path43 === "/capture") return handleCapture(req, res, "");
|
|
43024
|
+
const sessionMatch = path43.match(/^\/sessions\/([^/]+)(?:\/([^/]+))?$/);
|
|
42991
43025
|
if (sessionMatch) return handleSessionItem(req, res, decodeURIComponent(sessionMatch[1] ?? ""), sessionMatch[2] ?? "");
|
|
42992
|
-
if (
|
|
43026
|
+
if (path43 === "/ticket") {
|
|
42993
43027
|
if (req.method !== "POST") return methodNotAllowed(res);
|
|
42994
43028
|
if (!ctx.host.security.isTerminalAuthorized(req)) {
|
|
42995
43029
|
ctx.host.http.writeJson(res, 401, { error: "Unauthorized" });
|
|
@@ -43083,7 +43117,7 @@ function createAgentApi(ctx, terminalRuntime, deps) {
|
|
|
43083
43117
|
theaterId,
|
|
43084
43118
|
type: AGENT_OPERATION_TYPE,
|
|
43085
43119
|
pluginId: ctx.pluginId,
|
|
43086
|
-
title: session.label ??
|
|
43120
|
+
title: session.label ?? path28__default.basename(cwd),
|
|
43087
43121
|
payload: toOperationPayload(cwd, session),
|
|
43088
43122
|
createdAt: session.createdAt
|
|
43089
43123
|
});
|
|
@@ -43194,7 +43228,7 @@ function createAgentApi(ctx, terminalRuntime, deps) {
|
|
|
43194
43228
|
if (result?.renamed) {
|
|
43195
43229
|
observability.notifySessionUpdated(result.session);
|
|
43196
43230
|
const autoNameCwd = readPayloadString(ctx.host.operations.get(sessionId)?.payload ?? {}, "cwd") ?? result.session.cwdLabel;
|
|
43197
|
-
ctx.host.operations.patch(sessionId, { title: result.session.label ??
|
|
43231
|
+
ctx.host.operations.patch(sessionId, { title: result.session.label ?? path28__default.basename(autoNameCwd) });
|
|
43198
43232
|
}
|
|
43199
43233
|
ctx.host.http.writeJson(res, 200, { ok: true, renamed: result?.renamed === true });
|
|
43200
43234
|
return true;
|
|
@@ -43477,7 +43511,7 @@ function registerTerminalSettingsRoutes(ctx, deps) {
|
|
|
43477
43511
|
}
|
|
43478
43512
|
const updated = deps.globalOptionsService.update((current) => ({
|
|
43479
43513
|
...current,
|
|
43480
|
-
|
|
43514
|
+
...body
|
|
43481
43515
|
}));
|
|
43482
43516
|
ctx.host.http.writeJson(res, 200, toTerminalSettingsState(updated));
|
|
43483
43517
|
return true;
|
|
@@ -43488,14 +43522,17 @@ function registerTerminalSettingsRoutes(ctx, deps) {
|
|
|
43488
43522
|
}
|
|
43489
43523
|
function toTerminalSettingsState(data) {
|
|
43490
43524
|
return {
|
|
43491
|
-
enableMetaphor: data.enableMetaphor ?? false
|
|
43525
|
+
enableMetaphor: data.enableMetaphor ?? false,
|
|
43526
|
+
codexLaunchMode: data.codexLaunchMode ?? "acp"
|
|
43492
43527
|
};
|
|
43493
43528
|
}
|
|
43494
43529
|
function isTerminalSettingsBody(value) {
|
|
43495
43530
|
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
43496
|
-
|
|
43531
|
+
const keys = Object.keys(value);
|
|
43532
|
+
if (keys.length !== 1) return false;
|
|
43497
43533
|
const body = value;
|
|
43498
|
-
return typeof body.enableMetaphor === "boolean";
|
|
43534
|
+
if (keys[0] === "enableMetaphor") return typeof body.enableMetaphor === "boolean";
|
|
43535
|
+
return keys[0] === "codexLaunchMode" && (body.codexLaunchMode === "acp" || body.codexLaunchMode === "app-server");
|
|
43499
43536
|
}
|
|
43500
43537
|
function isJsonRequest(req) {
|
|
43501
43538
|
const contentType = req.headers["content-type"];
|