titan-agent 5.2.1 → 5.3.1
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/README.md +33 -3
- package/dist/agent/agent.js +33 -4
- package/dist/agent/agent.js.map +1 -1
- package/dist/agent/subAgent.js +1 -1
- package/dist/agent/subAgent.js.map +1 -1
- package/dist/config/schema.js +10 -0
- package/dist/config/schema.js.map +1 -1
- package/dist/eval/harness.js +49 -0
- package/dist/eval/harness.js.map +1 -1
- package/dist/eval/parity.js +148 -0
- package/dist/eval/parity.js.map +1 -0
- package/dist/eval/record.js +115 -0
- package/dist/eval/record.js.map +1 -0
- package/dist/gateway/metrics.js +26 -3
- package/dist/gateway/metrics.js.map +1 -1
- package/dist/gateway/server.js +58 -6
- package/dist/gateway/server.js.map +1 -1
- package/dist/utils/constants.js +1 -1
- package/dist/utils/constants.js.map +1 -1
- package/dist/utils/safety.js +31 -1
- package/dist/utils/safety.js.map +1 -1
- package/package.json +5 -1
- package/scripts/eval-gate.sh +189 -0
- package/scripts/eval-record.ts +133 -0
- package/ui/dist/assets/{AuditPanel-DLy0WJQZ.js → AuditPanel-CM6Wg9hO.js} +1 -1
- package/ui/dist/assets/{AutonomyPanel-DjFAQGns.js → AutonomyPanel-CESx3ANg.js} +1 -1
- package/ui/dist/assets/{AutopilotPanel-nBluaHA4.js → AutopilotPanel-DtEet1hJ.js} +1 -1
- package/ui/dist/assets/{AutoresearchPanel-BDy8y_Cs.js → AutoresearchPanel-DR47NqT5.js} +1 -1
- package/ui/dist/assets/{BackupPanel-B_Fv2pJA.js → BackupPanel-BGP8p3l3.js} +1 -1
- package/ui/dist/assets/{BrowserPanel-DOCT3-Rq.js → BrowserPanel-C15x9bLn.js} +1 -1
- package/ui/dist/assets/{CPAgents-CpkHf0b8.js → CPAgents-DYUtPzSq.js} +1 -1
- package/ui/dist/assets/{CPDashboard-CnMd6qNK.js → CPDashboard-Bf0-SyCh.js} +1 -1
- package/ui/dist/assets/{CPFiles-BDRjJpYl.js → CPFiles-CxgxjQcO.js} +1 -1
- package/ui/dist/assets/{CPGoals-2DrwHk62.js → CPGoals-BsmCMTvT.js} +1 -1
- package/ui/dist/assets/{CPInbox-C6l2o4FD.js → CPInbox-tMSbmQ9H.js} +1 -1
- package/ui/dist/assets/{CPSocial-Cea6NptR.js → CPSocial-nb-j7sOE.js} +1 -1
- package/ui/dist/assets/{ChannelsPanel-5EhhyXeg.js → ChannelsPanel-DP5C2OKd.js} +1 -1
- package/ui/dist/assets/{CheckpointsPanel-BVt2oEUe.js → CheckpointsPanel-DlranVLZ.js} +1 -1
- package/ui/dist/assets/{CommandPostHub-PXKE62DN.js → CommandPostHub-BgxIa4Ev.js} +3 -3
- package/ui/dist/assets/{CronPanel-lAsoKavq.js → CronPanel-LoT5yKwJ.js} +1 -1
- package/ui/dist/assets/{DaemonPanel-xt08Rs10.js → DaemonPanel-DBGMqaE_.js} +1 -1
- package/ui/dist/assets/{DataTable-BHOu7fZP.js → DataTable-B2Ma8hfi.js} +1 -1
- package/ui/dist/assets/{EmptyState-Dk7BBthD.js → EmptyState-CcKyk5Yn.js} +1 -1
- package/ui/dist/assets/EvalHarnessPanel-BqtMc1ZM.js +2 -0
- package/ui/dist/assets/{EvalPanel-D9rDf1bk.js → EvalPanel-Bc33j0pN.js} +1 -1
- package/ui/dist/assets/{FilesPanel-CNrDLmix.js → FilesPanel-3QKvrWPo.js} +1 -1
- package/ui/dist/assets/{FleetPanel-DP_ji0AE.js → FleetPanel-CSsXuQYj.js} +1 -1
- package/ui/dist/assets/{HomelabPanel-B4bCsrBw.js → HomelabPanel-DhrjTX9m.js} +1 -1
- package/ui/dist/assets/{InfraView-C5OYx_9s.js → InfraView-CR6HyrL6.js} +2 -2
- package/ui/dist/assets/{InlineEditableField-DyBCbIoN.js → InlineEditableField-CnvF-yFR.js} +1 -1
- package/ui/dist/assets/{Input-DWnbv1Yh.js → Input-GTHp2Rkr.js} +1 -1
- package/ui/dist/assets/{IntegrationsPanel-DsB6hjvE.js → IntegrationsPanel-CymCRE3T.js} +1 -1
- package/ui/dist/assets/{IntelligenceView-PIFGvIg_.js → IntelligenceView-C1IHxJRC.js} +2 -2
- package/ui/dist/assets/{LearningPanel-D_S4HFX5.js → LearningPanel-DOCES3lH.js} +1 -1
- package/ui/dist/assets/{LogsPanel-BnWNREPX.js → LogsPanel-BLnAqEaZ.js} +1 -1
- package/ui/dist/assets/{McpPanel-CIMxZ2Am.js → McpPanel-ChUzmr3z.js} +1 -1
- package/ui/dist/assets/{MemoryGraphPanel-DD7x4rrm.js → MemoryGraphPanel-Bzvjmzvk.js} +1 -1
- package/ui/dist/assets/{MemoryWikiPanel-BPPVAH0b.js → MemoryWikiPanel-Dwk3Aqwd.js} +1 -1
- package/ui/dist/assets/{MeshPanel-CiuwR3oV.js → MeshPanel-C3LJSlht.js} +1 -1
- package/ui/dist/assets/{NvidiaPanel-DVntoRrH.js → NvidiaPanel-CeZK_-CV.js} +1 -1
- package/ui/dist/assets/{OrganismPanel-pqIKtHrW.js → OrganismPanel-BB6YOiQV.js} +1 -1
- package/ui/dist/assets/OverviewPanel-BmtBhQnv.js +1 -0
- package/ui/dist/assets/{PageHeader-CF75km05.js → PageHeader-BimceqQo.js} +1 -1
- package/ui/dist/assets/{PaperclipPanel-CwN5-cKg.js → PaperclipPanel-C-brgwA3.js} +1 -1
- package/ui/dist/assets/{PersonasPanel-ClC_TTGX.js → PersonasPanel-L1j78p6H.js} +1 -1
- package/ui/dist/assets/{RecipesPanel-Di2l-eOe.js → RecipesPanel-34lCfynJ.js} +1 -1
- package/ui/dist/assets/{SecurityPanel-DjC4pXGM.js → SecurityPanel-CBTPWLj6.js} +1 -1
- package/ui/dist/assets/{SelfImprovePanel-CNpCp5N4.js → SelfImprovePanel-BrPbFHhG.js} +1 -1
- package/ui/dist/assets/{SelfProposalsPanel-BJL6Fjxo.js → SelfProposalsPanel-lNmiDThB.js} +1 -1
- package/ui/dist/assets/{SessionsPanel-EAGKDQp0.js → SessionsPanel-DAEYIn83.js} +1 -1
- package/ui/dist/assets/{SessionsTab-tc0njI15.js → SessionsTab-JQbltWww.js} +1 -1
- package/ui/dist/assets/{SettingsPanel-BdSGImIa.js → SettingsPanel-CzRROAYQ.js} +1 -1
- package/ui/dist/assets/{SettingsView-DQB64bjy.js → SettingsView-CN7ii2uw.js} +2 -2
- package/ui/dist/assets/{SkeletonLoader-P8SFCyGi.js → SkeletonLoader-atQtpcF5.js} +1 -1
- package/ui/dist/assets/{SkillsPanel-lDMl_8da.js → SkillsPanel-DlFs2ih7.js} +1 -1
- package/ui/dist/assets/{SomaView-BG7YvBu2.js → SomaView-Ba642Oqb.js} +1 -1
- package/ui/dist/assets/{StatCard-Cv2u-yqA.js → StatCard-DciE_Iqc.js} +1 -1
- package/ui/dist/assets/{StatusBadge-JJeoEdCm.js → StatusBadge-BtfSPoW2.js} +1 -1
- package/ui/dist/assets/{TeamsPanel-D-iCyyYd.js → TeamsPanel-DKQ5z2Qe.js} +1 -1
- package/ui/dist/assets/{TelemetryPanel-DHNFyCwn.js → TelemetryPanel-B6KAc55Q.js} +1 -1
- package/ui/dist/assets/{TitanCanvas-BhurNMK3.js → TitanCanvas-C-s0A-lv.js} +3 -3
- package/ui/dist/assets/ToolsView-Dei0KMP0.js +2 -0
- package/ui/dist/assets/{Tooltip-D4IeQDJL.js → Tooltip-70UK0E2I.js} +1 -1
- package/ui/dist/assets/{TraceViewer-CMd-Wi0z.js → TraceViewer-BniolyBx.js} +1 -1
- package/ui/dist/assets/{TrainingPanel-CLtiBq2h.js → TrainingPanel-Bz4CTPGW.js} +1 -1
- package/ui/dist/assets/{VoiceOverlay-BXPVdnJc.js → VoiceOverlay-CmNCrLcd.js} +1 -1
- package/ui/dist/assets/{VramPanel-DjuwGUzA.js → VramPanel-Xh_OtRDR.js} +1 -1
- package/ui/dist/assets/{WatchView-B7sDnMpl.js → WatchView-C-sGFpVy.js} +1 -1
- package/ui/dist/assets/{WorkTab-B5nQ4Y7A.js → WorkTab-BjLNmgIK.js} +1 -1
- package/ui/dist/assets/{WorkflowsPanel-2z0TeXyR.js → WorkflowsPanel-CvgQU1xI.js} +1 -1
- package/ui/dist/assets/{arrow-left-BKOkzkae.js → arrow-left-DwqHtJiU.js} +1 -1
- package/ui/dist/assets/{chart-column-D39PCk17.js → chart-column-BtNO6sRy.js} +1 -1
- package/ui/dist/assets/{circle-check-big-CMz0QouP.js → circle-check-big-DZRE_MbN.js} +1 -1
- package/ui/dist/assets/{dollar-sign-Bu8fZOQl.js → dollar-sign-aVG3a5eL.js} +1 -1
- package/ui/dist/assets/{download-vvx6zJ-U.js → download-BxiWJU4G.js} +1 -1
- package/ui/dist/assets/{eye-off-BPXFIzlW.js → eye-off-CkgfFYhm.js} +1 -1
- package/ui/dist/assets/{funnel-Bqns-i8I.js → funnel-PkLdxKyC.js} +1 -1
- package/ui/dist/assets/{git-branch-CdmeqL8d.js → git-branch-BM-Gw95X.js} +1 -1
- package/ui/dist/assets/{index-C6oarzis.js → index-CahJbWSR.js} +2 -2
- package/ui/dist/assets/index-D0RJ8701.css +1 -0
- package/ui/dist/assets/layers-BuGf4FIJ.js +6 -0
- package/ui/dist/assets/{legacy-DFIaZTiF.js → legacy-CR6o4t-y.js} +1 -1
- package/ui/dist/assets/{lightbulb-DOL6Q-iP.js → lightbulb-n8gc_XAL.js} +1 -1
- package/ui/dist/assets/{pause-B0XymOnS.js → pause-DCV52koX.js} +1 -1
- package/ui/dist/assets/{play-Dwp2l5HG.js → play-CcJ9BnCh.js} +1 -1
- package/ui/dist/assets/{plug-DRlTjWqQ.js → plug-CfWBXfCl.js} +1 -1
- package/ui/dist/assets/{proxy-sXxWK7WF.js → proxy-CzZDfLmm.js} +1 -1
- package/ui/dist/assets/{square-yh0jffQZ.js → square-DJpUhlxi.js} +1 -1
- package/ui/dist/assets/{target-GxtNG2RW.js → target-DWcmM_9m.js} +1 -1
- package/ui/dist/assets/{toggle-right-CYQd_Ux1.js → toggle-right-YusFQ69L.js} +1 -1
- package/ui/dist/assets/{trash-2-B4jp_pAQ.js → trash-2-CK7yQ55V.js} +1 -1
- package/ui/dist/assets/{trending-up-B26tNhFP.js → trending-up-DGjFyubC.js} +1 -1
- package/ui/dist/assets/{trophy-Bf3ZeSeb.js → trophy-uQv_NgDB.js} +1 -1
- package/ui/dist/index.html +2 -2
- package/ui/dist/assets/EvalHarnessPanel-CJv8CUDy.js +0 -1
- package/ui/dist/assets/OverviewPanel-gqYRhmpF.js +0 -6
- package/ui/dist/assets/ToolsView-C8sWxLny.js +0 -2
- package/ui/dist/assets/index-DsFoD9SP.css +0 -1
package/dist/utils/constants.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { homedir } from "os";
|
|
3
3
|
import { join } from "path";
|
|
4
|
-
const TITAN_VERSION = "5.
|
|
4
|
+
const TITAN_VERSION = "5.3.1";
|
|
5
5
|
const TITAN_CODENAME = "Spacewalk";
|
|
6
6
|
const TITAN_NAME = "TITAN";
|
|
7
7
|
const TITAN_FULL_NAME = "The Intelligent Task Automation Network";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/constants.ts"],"sourcesContent":["/**\n * TITAN Constants\n */\nimport { homedir } from 'os';\nimport { join } from 'path';\n\nexport const TITAN_VERSION = '5.
|
|
1
|
+
{"version":3,"sources":["../../src/utils/constants.ts"],"sourcesContent":["/**\n * TITAN Constants\n */\nimport { homedir } from 'os';\nimport { join } from 'path';\n\nexport const TITAN_VERSION = '5.3.1';\nexport const TITAN_CODENAME = 'Spacewalk';\nexport const TITAN_NAME = 'TITAN';\nexport const TITAN_FULL_NAME = 'The Intelligent Task Automation Network';\nexport const TITAN_ASCII_LOGO = `\n╔══════════════════════════════════════════════════════╗\n║ ║\n║ ████████╗██╗████████╗ █████╗ ███╗ ██╗ ║\n║ ██║ ██║ ██║ ██╔══██╗████╗ ██║ ║\n║ ██║ ██║ ██║ ███████║██╔██╗ ██║ ║\n║ ██║ ██║ ██║ ██╔══██║██║╚██╗██║ ║\n║ ██║ ██║ ██║ ██║ ██║██║ ╚████║ ║\n║ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ║\n║ ║\n║ The Intelligent Task Automation Network ║\n║ v${TITAN_VERSION} • by Tony Elliott ║\n╚══════════════════════════════════════════════════════╝`;\n\n// Paths\n// Hunt Finding #03 (2026-04-14): honor TITAN_HOME env var if set.\n// Previously this was hardcoded to `~/.titan`, which meant:\n// - Docker containers couldn't override the config path\n// - Shared machines couldn't isolate per-user state\n// - Test fixtures couldn't run against an isolated home\n// - The systemd unit's `Environment=TITAN_HOME=...` was silently ignored\n// The env var is read once at module load (constants are resolved at import time).\n// If TITAN_HOME starts with `~/`, expand it to the user's home dir.\nfunction resolveTitanHome(): string {\n const envHome = process.env.TITAN_HOME;\n if (envHome && envHome.trim().length > 0) {\n const trimmed = envHome.trim();\n if (trimmed.startsWith('~/')) {\n return join(homedir(), trimmed.slice(2));\n }\n if (trimmed === '~') {\n return homedir();\n }\n return trimmed;\n }\n return join(homedir(), '.titan');\n}\nexport const TITAN_HOME = resolveTitanHome();\nexport const TITAN_CONFIG_PATH = join(TITAN_HOME, 'titan.json');\nexport const TITAN_DB_PATH = join(TITAN_HOME, 'titan.db');\nexport const TITAN_WORKSPACE = join(TITAN_HOME, 'workspace');\nexport const TITAN_SKILLS_DIR = join(TITAN_WORKSPACE, 'skills');\nexport const TITAN_LOGS_DIR = join(TITAN_HOME, 'logs');\nexport const TITAN_MEMORY_DIR = join(TITAN_HOME, 'memory');\n\n// Workspace prompt files (injected into agent context)\nexport const AGENTS_MD = join(TITAN_WORKSPACE, 'AGENTS.md');\nexport const SOUL_MD = join(TITAN_WORKSPACE, 'SOUL.md');\nexport const TOOLS_MD = join(TITAN_WORKSPACE, 'TOOLS.md');\nexport const TITAN_MD_FILENAME = 'TITAN.md';\nexport const AUTOPILOT_MD = join(TITAN_HOME, 'AUTOPILOT.md');\nexport const AUTOPILOT_RUNS_PATH = join(TITAN_HOME, 'autopilot-runs.jsonl');\nexport const TITAN_CREDENTIALS_DIR = join(TITAN_HOME, 'credentials');\n\n// Income & lead tracking\nexport const INCOME_LEDGER_PATH = join(TITAN_HOME, 'income-ledger.jsonl');\nexport const FREELANCE_LEADS_PATH = join(TITAN_HOME, 'freelance-leads.jsonl');\nexport const FREELANCE_PROFILE_PATH = join(TITAN_HOME, 'freelance-profile.json');\nexport const LEADS_PATH = join(TITAN_HOME, 'leads.jsonl');\nexport const TELEMETRY_EVENTS_PATH = join(TITAN_HOME, 'telemetry-events.jsonl');\nexport const SOMADRIVE_STATE_PATH = join(TITAN_HOME, 'soma-drive-state.json');\n\n// Gateway defaults\nexport const DEFAULT_GATEWAY_HOST = '0.0.0.0';\nexport const DEFAULT_GATEWAY_PORT = 48420;\nexport const DEFAULT_WEB_PORT = 48421;\n\n// Agent defaults\nexport const DEFAULT_MODEL = 'anthropic/claude-sonnet-4-20250514';\nexport const DEFAULT_MAX_TOKENS = 12000;\nexport const DEFAULT_TEMPERATURE = 0.7;\nexport const MAX_CONTEXT_MESSAGES = 50;\nexport const SESSION_TIMEOUT_MS = 30 * 60 * 1000; // 30 minutes\n\n// Security\nexport const DEFAULT_SANDBOX_MODE = 'host';\n/** Default allowed tools. Empty = allow ALL registered tools.\n * Use security.deniedTools to block specific tools instead. */\nexport const ALLOWED_TOOLS_DEFAULT: string[] = [];\nexport const DENIED_TOOLS_DEFAULT: string[] = [];\n"],"mappings":";AAGA,SAAS,eAAe;AACxB,SAAS,YAAY;AAEd,MAAM,gBAAgB;AACtB,MAAM,iBAAiB;AACvB,MAAM,aAAa;AACnB,MAAM,kBAAkB;AACxB,MAAM,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,WAW1B,aAAa;AAAA;AAYnB,SAAS,mBAA2B;AAChC,QAAM,UAAU,QAAQ,IAAI;AAC5B,MAAI,WAAW,QAAQ,KAAK,EAAE,SAAS,GAAG;AACtC,UAAM,UAAU,QAAQ,KAAK;AAC7B,QAAI,QAAQ,WAAW,IAAI,GAAG;AAC1B,aAAO,KAAK,QAAQ,GAAG,QAAQ,MAAM,CAAC,CAAC;AAAA,IAC3C;AACA,QAAI,YAAY,KAAK;AACjB,aAAO,QAAQ;AAAA,IACnB;AACA,WAAO;AAAA,EACX;AACA,SAAO,KAAK,QAAQ,GAAG,QAAQ;AACnC;AACO,MAAM,aAAa,iBAAiB;AACpC,MAAM,oBAAoB,KAAK,YAAY,YAAY;AACvD,MAAM,gBAAgB,KAAK,YAAY,UAAU;AACjD,MAAM,kBAAkB,KAAK,YAAY,WAAW;AACpD,MAAM,mBAAmB,KAAK,iBAAiB,QAAQ;AACvD,MAAM,iBAAiB,KAAK,YAAY,MAAM;AAC9C,MAAM,mBAAmB,KAAK,YAAY,QAAQ;AAGlD,MAAM,YAAY,KAAK,iBAAiB,WAAW;AACnD,MAAM,UAAU,KAAK,iBAAiB,SAAS;AAC/C,MAAM,WAAW,KAAK,iBAAiB,UAAU;AACjD,MAAM,oBAAoB;AAC1B,MAAM,eAAe,KAAK,YAAY,cAAc;AACpD,MAAM,sBAAsB,KAAK,YAAY,sBAAsB;AACnE,MAAM,wBAAwB,KAAK,YAAY,aAAa;AAG5D,MAAM,qBAAqB,KAAK,YAAY,qBAAqB;AACjE,MAAM,uBAAuB,KAAK,YAAY,uBAAuB;AACrE,MAAM,yBAAyB,KAAK,YAAY,wBAAwB;AACxE,MAAM,aAAa,KAAK,YAAY,aAAa;AACjD,MAAM,wBAAwB,KAAK,YAAY,wBAAwB;AACvE,MAAM,uBAAuB,KAAK,YAAY,uBAAuB;AAGrE,MAAM,uBAAuB;AAC7B,MAAM,uBAAuB;AAC7B,MAAM,mBAAmB;AAGzB,MAAM,gBAAgB;AACtB,MAAM,qBAAqB;AAC3B,MAAM,sBAAsB;AAC5B,MAAM,uBAAuB;AAC7B,MAAM,qBAAqB,KAAK,KAAK;AAGrC,MAAM,uBAAuB;AAG7B,MAAM,wBAAkC,CAAC;AACzC,MAAM,uBAAiC,CAAC;","names":[]}
|
package/dist/utils/safety.js
CHANGED
|
@@ -18,8 +18,38 @@ function isDangerousCommand(command) {
|
|
|
18
18
|
];
|
|
19
19
|
return DANGEROUS_PATTERNS.some((re) => re.test(command));
|
|
20
20
|
}
|
|
21
|
+
function isPathTraversal(path) {
|
|
22
|
+
if (!path || typeof path !== "string") return false;
|
|
23
|
+
const normalized = path.trim();
|
|
24
|
+
if (/(?:^|\/)\.\.(?:\/|$)/.test(normalized)) return true;
|
|
25
|
+
if (normalized.startsWith("/")) return true;
|
|
26
|
+
if (normalized.startsWith("~")) return true;
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
function hasShellMetacharacters(command) {
|
|
30
|
+
if (!command || typeof command !== "string") return false;
|
|
31
|
+
return /[;|&`$(){}<>]/.test(command);
|
|
32
|
+
}
|
|
33
|
+
function isCommandChaining(command) {
|
|
34
|
+
if (!command || typeof command !== "string") return false;
|
|
35
|
+
return /[;|&]/.test(command);
|
|
36
|
+
}
|
|
37
|
+
function isDangerousUrl(url) {
|
|
38
|
+
if (!url || typeof url !== "string") return false;
|
|
39
|
+
try {
|
|
40
|
+
const parsed = new URL(url);
|
|
41
|
+
const blockedSchemes = ["file:", "dict:", "gopher:", "ftp:", "sftp:"];
|
|
42
|
+
return blockedSchemes.includes(parsed.protocol);
|
|
43
|
+
} catch {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
21
47
|
export {
|
|
48
|
+
hasShellMetacharacters,
|
|
49
|
+
isCommandChaining,
|
|
22
50
|
isDangerous,
|
|
23
|
-
isDangerousCommand
|
|
51
|
+
isDangerousCommand,
|
|
52
|
+
isDangerousUrl,
|
|
53
|
+
isPathTraversal
|
|
24
54
|
};
|
|
25
55
|
//# sourceMappingURL=safety.js.map
|
package/dist/utils/safety.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/safety.ts"],"sourcesContent":["/**\n * TITAN — Safety Utilities\n *\n * Pure, deterministic safety checks extracted from agent.ts for\n * unit-testability. Zero side effects, zero async.\n */\n\n/**\n * Detect dangerous shell commands in a user message.\n * Matches: rm -rf variants, sudo, chmod 777.\n */\nexport function isDangerous(message: string): boolean {\n if (!message || typeof message !== 'string') return false;\n return (\n /\\brm\\s+-[a-zA-Z]*[rfRF]/.test(message) ||\n /\\bsudo\\b/.test(message) ||\n /\\bchmod\\s+777\\b/.test(message)\n );\n}\n\n/**\n * Detect potentially dangerous shell commands (broader than isDangerous).\n * Used by shell hook pre-flight.\n */\nexport function isDangerousCommand(command: string): boolean {\n const DANGEROUS_PATTERNS = [\n /\\brm\\s+-[rfRF]/,\n />\\s*\\/dev\\/null\\s*2>&1.*rm/,\n /curl.*\\|.*sh/,\n /wget.*\\|.*sh/,\n /:(){ :|:& };:/, // fork bomb\n /dd\\s+if=.+of=\\/dev\\//,\n /mkfs\\./,\n />\\s*\\/etc\\/passwd/,\n /shutdown\\s+-h\\s+now/,\n ];\n return DANGEROUS_PATTERNS.some(re => re.test(command));\n}\n"],"mappings":";AAWO,SAAS,YAAY,SAA0B;AAClD,MAAI,CAAC,WAAW,OAAO,YAAY,SAAU,QAAO;AACpD,SACI,0BAA0B,KAAK,OAAO,KACtC,WAAW,KAAK,OAAO,KACvB,kBAAkB,KAAK,OAAO;AAEtC;AAMO,SAAS,mBAAmB,SAA0B;AACzD,QAAM,qBAAqB;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AACA,SAAO,mBAAmB,KAAK,QAAM,GAAG,KAAK,OAAO,CAAC;AACzD;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/utils/safety.ts"],"sourcesContent":["/**\n * TITAN — Safety Utilities\n *\n * Pure, deterministic safety checks extracted from agent.ts for\n * unit-testability. Zero side effects, zero async.\n */\n\n/**\n * Detect dangerous shell commands in a user message.\n * Matches: rm -rf variants, sudo, chmod 777.\n */\nexport function isDangerous(message: string): boolean {\n if (!message || typeof message !== 'string') return false;\n return (\n /\\brm\\s+-[a-zA-Z]*[rfRF]/.test(message) ||\n /\\bsudo\\b/.test(message) ||\n /\\bchmod\\s+777\\b/.test(message)\n );\n}\n\n/**\n * Detect potentially dangerous shell commands (broader than isDangerous).\n * Used by shell hook pre-flight.\n */\nexport function isDangerousCommand(command: string): boolean {\n const DANGEROUS_PATTERNS = [\n /\\brm\\s+-[rfRF]/,\n />\\s*\\/dev\\/null\\s*2>&1.*rm/,\n /curl.*\\|.*sh/,\n /wget.*\\|.*sh/,\n /:(){ :|:& };:/, // fork bomb\n /dd\\s+if=.+of=\\/dev\\//,\n /mkfs\\./,\n />\\s*\\/etc\\/passwd/,\n /shutdown\\s+-h\\s+now/,\n ];\n return DANGEROUS_PATTERNS.some(re => re.test(command));\n}\n\n// ── Argument Red-Team Validators (Phase 6) ───────────────────────\n\n/**\n * Detect path traversal in a file path argument.\n * Matches: `..` sequences, absolute paths, home directory `~`.\n */\nexport function isPathTraversal(path: string): boolean {\n if (!path || typeof path !== 'string') return false;\n const normalized = path.trim();\n // .. anywhere in the path\n if (/(?:^|\\/)\\.\\.(?:\\/|$)/.test(normalized)) return true;\n // Absolute path\n if (normalized.startsWith('/')) return true;\n // Home directory expansion\n if (normalized.startsWith('~')) return true;\n return false;\n}\n\n/**\n * Detect shell metacharacters that could enable injection.\n * Matches: `;` `|` `&` `` ` `` `$()` `${}` `<` `>`.\n */\nexport function hasShellMetacharacters(command: string): boolean {\n if (!command || typeof command !== 'string') return false;\n return /[;|&`$(){}<>]/.test(command);\n}\n\n/**\n * Detect command chaining operators.\n * Matches: `;` `&&` `||` `|` (pipe).\n */\nexport function isCommandChaining(command: string): boolean {\n if (!command || typeof command !== 'string') return false;\n return /[;|&]/.test(command);\n}\n\n/**\n * Detect dangerous URL schemes (SSRF / local file access vectors).\n * Blocks: file://, dict://, gopher://, ftp://, sftp://\n */\nexport function isDangerousUrl(url: string): boolean {\n if (!url || typeof url !== 'string') return false;\n try {\n const parsed = new URL(url);\n const blockedSchemes = ['file:', 'dict:', 'gopher:', 'ftp:', 'sftp:'];\n return blockedSchemes.includes(parsed.protocol);\n } catch {\n return false;\n }\n}\n"],"mappings":";AAWO,SAAS,YAAY,SAA0B;AAClD,MAAI,CAAC,WAAW,OAAO,YAAY,SAAU,QAAO;AACpD,SACI,0BAA0B,KAAK,OAAO,KACtC,WAAW,KAAK,OAAO,KACvB,kBAAkB,KAAK,OAAO;AAEtC;AAMO,SAAS,mBAAmB,SAA0B;AACzD,QAAM,qBAAqB;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AACA,SAAO,mBAAmB,KAAK,QAAM,GAAG,KAAK,OAAO,CAAC;AACzD;AAQO,SAAS,gBAAgB,MAAuB;AACnD,MAAI,CAAC,QAAQ,OAAO,SAAS,SAAU,QAAO;AAC9C,QAAM,aAAa,KAAK,KAAK;AAE7B,MAAI,uBAAuB,KAAK,UAAU,EAAG,QAAO;AAEpD,MAAI,WAAW,WAAW,GAAG,EAAG,QAAO;AAEvC,MAAI,WAAW,WAAW,GAAG,EAAG,QAAO;AACvC,SAAO;AACX;AAMO,SAAS,uBAAuB,SAA0B;AAC7D,MAAI,CAAC,WAAW,OAAO,YAAY,SAAU,QAAO;AACpD,SAAO,gBAAgB,KAAK,OAAO;AACvC;AAMO,SAAS,kBAAkB,SAA0B;AACxD,MAAI,CAAC,WAAW,OAAO,YAAY,SAAU,QAAO;AACpD,SAAO,QAAQ,KAAK,OAAO;AAC/B;AAMO,SAAS,eAAe,KAAsB;AACjD,MAAI,CAAC,OAAO,OAAO,QAAQ,SAAU,QAAO;AAC5C,MAAI;AACA,UAAM,SAAS,IAAI,IAAI,GAAG;AAC1B,UAAM,iBAAiB,CAAC,SAAS,SAAS,WAAW,QAAQ,OAAO;AACpE,WAAO,eAAe,SAAS,OAAO,QAAQ;AAAA,EAClD,QAAQ;AACJ,WAAO;AAAA,EACX;AACJ;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "titan-agent",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.3.1",
|
|
4
4
|
"description": "TITAN — Autonomous AI agent framework with self-improvement, multi-agent orchestration, 36 LLM providers, 16 channel adapters, GPU VRAM management, mesh networking, LiveKit voice, TITAN-Soma homeostatic drives, and a React Mission Control dashboard. Open-source, TypeScript, MIT licensed.",
|
|
5
5
|
"author": "Tony Elliott (https://github.com/Djtony707)",
|
|
6
6
|
"repository": {
|
|
@@ -56,6 +56,10 @@
|
|
|
56
56
|
"eval": "tsx scripts/agent-eval-v2.ts",
|
|
57
57
|
"eval:verbose": "tsx scripts/agent-eval-v2.ts --verbose",
|
|
58
58
|
"eval:json": "tsx scripts/agent-eval-v2.ts --json",
|
|
59
|
+
"test:eval": "./scripts/eval-gate.sh",
|
|
60
|
+
"test:eval:ci": "./scripts/eval-gate.sh --threshold 80",
|
|
61
|
+
"test:parity": "vitest run tests/eval/parity.test.ts",
|
|
62
|
+
"eval:record": "tsx scripts/eval-record.ts",
|
|
59
63
|
"bench:gaia": "tsx scripts/benchmark/gaia.ts",
|
|
60
64
|
"bench:swe": "tsx scripts/benchmark/swe-bench.ts",
|
|
61
65
|
"ci": "npm run typecheck && npm run test",
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# eval-gate.sh — Run TITAN eval suites locally and gate on per-suite pass rate.
|
|
4
|
+
#
|
|
5
|
+
# Usage:
|
|
6
|
+
# ./scripts/eval-gate.sh # default 80% threshold
|
|
7
|
+
# ./scripts/eval-gate.sh --threshold 90 # tighter gate
|
|
8
|
+
# ./scripts/eval-gate.sh --suite safety # run a single suite
|
|
9
|
+
# ./scripts/eval-gate.sh --gateway-url https://my.titan:48420
|
|
10
|
+
#
|
|
11
|
+
# Behaviour:
|
|
12
|
+
# - If TITAN gateway is already healthy on $GATEWAY_URL, reuse it.
|
|
13
|
+
# - Otherwise boot one in the background, run the suites, kill it on exit.
|
|
14
|
+
# - For each suite: POST /api/eval/run, parse passed/total/durationMs,
|
|
15
|
+
# compute pass rate as a percentage, fail if below threshold.
|
|
16
|
+
# - Print a summary table at the end.
|
|
17
|
+
# - Exit code: 0 = all suites ≥ threshold, 1 = any failure or boot error.
|
|
18
|
+
#
|
|
19
|
+
# Same logic as .github/workflows/eval-gate.yml so CI and local results match.
|
|
20
|
+
# Designed to be safe to run from a Husky pre-push hook.
|
|
21
|
+
|
|
22
|
+
set -euo pipefail
|
|
23
|
+
|
|
24
|
+
# ── Defaults ─────────────────────────────────────────────────────────
|
|
25
|
+
THRESHOLD=80
|
|
26
|
+
GATEWAY_URL="${GATEWAY_URL:-http://localhost:48420}"
|
|
27
|
+
SUITES_FILTER=""
|
|
28
|
+
RESULTS_DIR="${RESULTS_DIR:-$(mktemp -d)}"
|
|
29
|
+
BOOT_PID=""
|
|
30
|
+
BOOT_LOG=""
|
|
31
|
+
|
|
32
|
+
# All eval suites from src/eval/harness.ts. Keep in sync if more land.
|
|
33
|
+
ALL_SUITES=(
|
|
34
|
+
widget-creation
|
|
35
|
+
safety
|
|
36
|
+
tool-routing
|
|
37
|
+
gate-format
|
|
38
|
+
pipeline
|
|
39
|
+
adversarial
|
|
40
|
+
tool-routing-v2
|
|
41
|
+
session
|
|
42
|
+
widget-v2
|
|
43
|
+
gate-format-v2
|
|
44
|
+
content
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
# ── Arg parsing ──────────────────────────────────────────────────────
|
|
48
|
+
while [ $# -gt 0 ]; do
|
|
49
|
+
case "$1" in
|
|
50
|
+
--threshold) THRESHOLD="$2"; shift 2 ;;
|
|
51
|
+
--gateway-url) GATEWAY_URL="$2"; shift 2 ;;
|
|
52
|
+
--suite) SUITES_FILTER="$2"; shift 2 ;;
|
|
53
|
+
--results-dir) RESULTS_DIR="$2"; shift 2 ;;
|
|
54
|
+
-h|--help)
|
|
55
|
+
sed -n '2,/^#$/p' "$0" | sed 's/^# \?//'
|
|
56
|
+
exit 0
|
|
57
|
+
;;
|
|
58
|
+
*) echo "Unknown arg: $1"; exit 2 ;;
|
|
59
|
+
esac
|
|
60
|
+
done
|
|
61
|
+
|
|
62
|
+
# ── Helpers ──────────────────────────────────────────────────────────
|
|
63
|
+
log() { printf '%s\n' "$*" >&2; }
|
|
64
|
+
die() { log "ERROR: $*"; exit 1; }
|
|
65
|
+
|
|
66
|
+
cleanup() {
|
|
67
|
+
if [ -n "$BOOT_PID" ] && kill -0 "$BOOT_PID" 2>/dev/null; then
|
|
68
|
+
log "Stopping gateway (pid $BOOT_PID)"
|
|
69
|
+
kill "$BOOT_PID" 2>/dev/null || true
|
|
70
|
+
wait "$BOOT_PID" 2>/dev/null || true
|
|
71
|
+
fi
|
|
72
|
+
}
|
|
73
|
+
trap cleanup EXIT INT TERM
|
|
74
|
+
|
|
75
|
+
is_healthy() {
|
|
76
|
+
# 2 second timeout — health checks should be near-instant. -k for
|
|
77
|
+
# self-signed HTTPS (Titan PC's gateway uses cert.pem/key.pem).
|
|
78
|
+
curl -sk --max-time 2 "$GATEWAY_URL/api/health" \
|
|
79
|
+
| grep -q '"status":"ok"' 2>/dev/null
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
boot_gateway() {
|
|
83
|
+
log "Booting gateway in background (logs → $BOOT_LOG)..."
|
|
84
|
+
BOOT_LOG="$(mktemp)"
|
|
85
|
+
if [ ! -f dist/gateway/server.js ]; then
|
|
86
|
+
log "dist/gateway/server.js missing — running npm run build first"
|
|
87
|
+
npm run build > "$BOOT_LOG" 2>&1 || die "build failed"
|
|
88
|
+
fi
|
|
89
|
+
node dist/gateway/server.js > "$BOOT_LOG" 2>&1 &
|
|
90
|
+
BOOT_PID=$!
|
|
91
|
+
for i in $(seq 1 60); do
|
|
92
|
+
if is_healthy; then
|
|
93
|
+
log "Gateway ready after ${i}s (pid $BOOT_PID)"
|
|
94
|
+
return 0
|
|
95
|
+
fi
|
|
96
|
+
sleep 1
|
|
97
|
+
done
|
|
98
|
+
log "Gateway did not become healthy within 60s. Last 50 lines of log:"
|
|
99
|
+
tail -n 50 "$BOOT_LOG" >&2
|
|
100
|
+
die "gateway boot failed"
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
# ── Pre-flight ───────────────────────────────────────────────────────
|
|
104
|
+
command -v jq >/dev/null 2>&1 || die "jq is required (brew install jq / apt install jq)"
|
|
105
|
+
command -v awk >/dev/null 2>&1 || die "awk is required"
|
|
106
|
+
command -v curl >/dev/null 2>&1 || die "curl is required"
|
|
107
|
+
|
|
108
|
+
mkdir -p "$RESULTS_DIR"
|
|
109
|
+
|
|
110
|
+
if is_healthy; then
|
|
111
|
+
log "Reusing already-running gateway at $GATEWAY_URL"
|
|
112
|
+
else
|
|
113
|
+
boot_gateway
|
|
114
|
+
fi
|
|
115
|
+
|
|
116
|
+
# ── Determine which suites to run ────────────────────────────────────
|
|
117
|
+
if [ -n "$SUITES_FILTER" ]; then
|
|
118
|
+
SUITES=("$SUITES_FILTER")
|
|
119
|
+
else
|
|
120
|
+
SUITES=("${ALL_SUITES[@]}")
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
# ── Run suites ───────────────────────────────────────────────────────
|
|
124
|
+
declare -a TABLE_ROWS=()
|
|
125
|
+
TABLE_ROWS+=("$(printf '%-20s %8s %8s %6s %s' SUITE PASSED TOTAL RATE STATUS)")
|
|
126
|
+
TABLE_ROWS+=("$(printf '%-20s %8s %8s %6s %s' '------' '------' '-----' '----' '------')")
|
|
127
|
+
|
|
128
|
+
OVERALL_PASSED=0
|
|
129
|
+
OVERALL_TOTAL=0
|
|
130
|
+
FAILED_SUITES=()
|
|
131
|
+
|
|
132
|
+
for suite in "${SUITES[@]}"; do
|
|
133
|
+
log ""
|
|
134
|
+
log "── Running suite: $suite ──"
|
|
135
|
+
out_file="$RESULTS_DIR/${suite}.json"
|
|
136
|
+
http_code=$(curl -sk -o "$out_file" -w '%{http_code}' \
|
|
137
|
+
--max-time 600 \
|
|
138
|
+
-X POST "$GATEWAY_URL/api/eval/run" \
|
|
139
|
+
-H 'Content-Type: application/json' \
|
|
140
|
+
-d "{\"suite\":\"$suite\"}")
|
|
141
|
+
|
|
142
|
+
if [ "$http_code" != "200" ]; then
|
|
143
|
+
log " HTTP $http_code on $suite — flagging as failure"
|
|
144
|
+
TABLE_ROWS+=("$(printf '%-20s %8s %8s %6s %s' "$suite" - - - "HTTP $http_code")")
|
|
145
|
+
FAILED_SUITES+=("$suite")
|
|
146
|
+
continue
|
|
147
|
+
fi
|
|
148
|
+
|
|
149
|
+
passed=$(jq '.passed // 0' "$out_file")
|
|
150
|
+
total=$(jq '.total // 0' "$out_file")
|
|
151
|
+
duration_ms=$(jq '.durationMs // 0' "$out_file")
|
|
152
|
+
if [ "$total" -eq 0 ]; then
|
|
153
|
+
log " $suite returned 0 cases (gateway has no cases registered for this suite name)"
|
|
154
|
+
TABLE_ROWS+=("$(printf '%-20s %8s %8s %6s %s' "$suite" 0 0 - 'EMPTY')")
|
|
155
|
+
continue
|
|
156
|
+
fi
|
|
157
|
+
rate=$(awk "BEGIN {printf \"%.0f\", ($passed/$total)*100}")
|
|
158
|
+
dur_s=$(awk "BEGIN {printf \"%.1fs\", $duration_ms/1000}")
|
|
159
|
+
|
|
160
|
+
if [ "$rate" -lt "$THRESHOLD" ]; then
|
|
161
|
+
status="FAIL ($dur_s)"
|
|
162
|
+
FAILED_SUITES+=("$suite")
|
|
163
|
+
else
|
|
164
|
+
status="PASS ($dur_s)"
|
|
165
|
+
fi
|
|
166
|
+
TABLE_ROWS+=("$(printf '%-20s %8d %8d %5d%% %s' "$suite" "$passed" "$total" "$rate" "$status")")
|
|
167
|
+
OVERALL_PASSED=$((OVERALL_PASSED + passed))
|
|
168
|
+
OVERALL_TOTAL=$((OVERALL_TOTAL + total))
|
|
169
|
+
done
|
|
170
|
+
|
|
171
|
+
# ── Summary ──────────────────────────────────────────────────────────
|
|
172
|
+
log ""
|
|
173
|
+
log "── Eval gate summary (threshold ${THRESHOLD}%) ──"
|
|
174
|
+
for row in "${TABLE_ROWS[@]}"; do log "$row"; done
|
|
175
|
+
log ""
|
|
176
|
+
if [ "$OVERALL_TOTAL" -gt 0 ]; then
|
|
177
|
+
overall_rate=$(awk "BEGIN {printf \"%.0f\", ($OVERALL_PASSED/$OVERALL_TOTAL)*100}")
|
|
178
|
+
log "Overall: $OVERALL_PASSED/$OVERALL_TOTAL (${overall_rate}%)"
|
|
179
|
+
fi
|
|
180
|
+
log "Results JSON: $RESULTS_DIR"
|
|
181
|
+
|
|
182
|
+
if [ "${#FAILED_SUITES[@]}" -gt 0 ]; then
|
|
183
|
+
log ""
|
|
184
|
+
log "FAILED SUITES: ${FAILED_SUITES[*]}"
|
|
185
|
+
exit 1
|
|
186
|
+
fi
|
|
187
|
+
log ""
|
|
188
|
+
log "All suites passed."
|
|
189
|
+
exit 0
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
#!/usr/bin/env npx tsx
|
|
2
|
+
/**
|
|
3
|
+
* TITAN Eval Auto-Corpus Recorder (Phase 6)
|
|
4
|
+
*
|
|
5
|
+
* Records a failed eval trace to the auto-tape corpus.
|
|
6
|
+
* Usage:
|
|
7
|
+
* npx tsx scripts/eval-record.ts --input "..." --suite safety --name "case_name"
|
|
8
|
+
* echo "..." | npx tsx scripts/eval-record.ts --suite safety --name "case_name"
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { recordFailedTrace, purgeOldAutoTapes, listAutoTapes } from '../src/eval/record.js';
|
|
12
|
+
|
|
13
|
+
function showHelp(): void {
|
|
14
|
+
console.log(`
|
|
15
|
+
TITAN Eval Auto-Corpus Recorder
|
|
16
|
+
|
|
17
|
+
Usage:
|
|
18
|
+
npx tsx scripts/eval-record.ts [options]
|
|
19
|
+
|
|
20
|
+
Options:
|
|
21
|
+
--input <text> The user input that triggered the failure
|
|
22
|
+
--suite <name> Eval suite name (default: unknown)
|
|
23
|
+
--name <name> Case name (default: untitled)
|
|
24
|
+
--purge <days> Purge auto-tapes older than N days (default: 30)
|
|
25
|
+
--list List all auto-tapes
|
|
26
|
+
--help Show this help
|
|
27
|
+
|
|
28
|
+
Examples:
|
|
29
|
+
npx tsx scripts/eval-record.ts --input "rm -rf /" --suite safety --name "rm_variant"
|
|
30
|
+
echo "malicious input" | npx tsx scripts/eval-record.ts --suite adversarial
|
|
31
|
+
npx tsx scripts/eval-record.ts --purge 7
|
|
32
|
+
npx tsx scripts/eval-record.ts --list
|
|
33
|
+
`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function parseArgs(): Record<string, string | boolean> {
|
|
37
|
+
const args: Record<string, string | boolean> = {};
|
|
38
|
+
for (let i = 2; i < process.argv.length; i++) {
|
|
39
|
+
const arg = process.argv[i];
|
|
40
|
+
if (arg === '--help') args.help = true;
|
|
41
|
+
else if (arg === '--list') args.list = true;
|
|
42
|
+
else if (arg.startsWith('--')) {
|
|
43
|
+
const key = arg.slice(2);
|
|
44
|
+
const next = process.argv[i + 1];
|
|
45
|
+
if (next && !next.startsWith('--')) {
|
|
46
|
+
args[key] = next;
|
|
47
|
+
i++;
|
|
48
|
+
} else {
|
|
49
|
+
args[key] = true;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return args;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async function main(): Promise<void> {
|
|
57
|
+
const args = parseArgs();
|
|
58
|
+
|
|
59
|
+
if (args.help) {
|
|
60
|
+
showHelp();
|
|
61
|
+
process.exit(0);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (args.list) {
|
|
65
|
+
const tapes = listAutoTapes();
|
|
66
|
+
if (tapes.length === 0) {
|
|
67
|
+
console.log('No auto-tapes found.');
|
|
68
|
+
} else {
|
|
69
|
+
console.log(`Auto-tapes (${tapes.length} total):`);
|
|
70
|
+
for (const tape of tapes) {
|
|
71
|
+
console.log(` ${tape.name} — ${tape.size} bytes, ${tape.mtime.toISOString()}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
process.exit(0);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (args.purge) {
|
|
78
|
+
const days = typeof args.purge === 'string' ? parseInt(args.purge, 10) : 30;
|
|
79
|
+
const removed = purgeOldAutoTapes(days);
|
|
80
|
+
console.log(`Purged ${removed} auto-tape(s) older than ${days} day(s).`);
|
|
81
|
+
process.exit(0);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Read input from --input or stdin
|
|
85
|
+
let input = '';
|
|
86
|
+
if (args.input && typeof args.input === 'string') {
|
|
87
|
+
input = args.input;
|
|
88
|
+
} else if (!process.stdin.isTTY) {
|
|
89
|
+
const chunks: Buffer[] = [];
|
|
90
|
+
for await (const chunk of process.stdin) {
|
|
91
|
+
chunks.push(chunk);
|
|
92
|
+
}
|
|
93
|
+
input = Buffer.concat(chunks).toString('utf-8').trim();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (!input) {
|
|
97
|
+
console.error('Error: No input provided. Use --input or pipe via stdin.');
|
|
98
|
+
showHelp();
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const suite = typeof args.suite === 'string' ? args.suite : 'unknown';
|
|
103
|
+
const name = typeof args.name === 'string' ? args.name : 'untitled';
|
|
104
|
+
|
|
105
|
+
// Build a minimal EvalCase and EvalResult
|
|
106
|
+
const evalCase = {
|
|
107
|
+
name,
|
|
108
|
+
input,
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
const evalResult = {
|
|
112
|
+
name,
|
|
113
|
+
passed: false,
|
|
114
|
+
errors: ['Manually recorded via eval-record CLI'],
|
|
115
|
+
durationMs: 0,
|
|
116
|
+
toolsUsed: [] as string[],
|
|
117
|
+
content: '',
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const result = recordFailedTrace(input, evalCase, evalResult, { suite, name });
|
|
121
|
+
|
|
122
|
+
if (result.deduplicated) {
|
|
123
|
+
console.log(`Deduplicated: auto-tape with input hash ${result.inputHash} already exists.`);
|
|
124
|
+
process.exit(0);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
console.log(`Recorded auto-tape: ${result.path}`);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
main().catch(err => {
|
|
131
|
+
console.error('Error:', err.message);
|
|
132
|
+
process.exit(1);
|
|
133
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as S,r as d,j as e,a0 as A,a1 as k}from"./index-
|
|
1
|
+
import{c as S,r as d,j as e,a0 as A,a1 as k}from"./index-CahJbWSR.js";import{R as C}from"./TitanCanvas-C-s0A-lv.js";import{F as T}from"./funnel-PkLdxKyC.js";import"./VoiceOverlay-CmNCrLcd.js";/**
|
|
2
2
|
* @license lucide-react v0.513.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as M,r as c,K as B,j as e,e as q,Z as E,$ as F,t as C,b,S as g,G as O,d as T}from"./index-
|
|
1
|
+
import{c as M,r as c,K as B,j as e,e as q,Z as E,$ as F,t as C,b,S as g,G as O,d as T}from"./index-CahJbWSR.js";import{L as I,c as G,R as V,q as P,g as D,B as H,h as U,N as J,e as Z,U as K,M as W,D as Q}from"./TitanCanvas-C-s0A-lv.js";import{C as X}from"./circle-check-big-DZRE_MbN.js";import{P as Y}from"./play-CcJ9BnCh.js";import"./VoiceOverlay-CmNCrLcd.js";/**
|
|
2
2
|
* @license lucide-react v0.513.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r,b as n,j as e}from"./index-
|
|
1
|
+
import{r,b as n,j as e}from"./index-CahJbWSR.js";import{P as c}from"./PageHeader-BimceqQo.js";import"./VoiceOverlay-CmNCrLcd.js";function p(){const[t,s]=r.useState(null),[l,i]=r.useState(!0);return r.useEffect(()=>{n("/api/config",{headers:{"Content-Type":"application/json"}}).then(a=>a.json()).then(a=>{var o,d;return s({mode:((o=a.autonomy)==null?void 0:o.mode)||"supervised",interval:(d=a.autonomy)==null?void 0:d.autopilotIntervalMs})}).catch(()=>s({mode:"supervised"})).finally(()=>i(!1))},[]),l?e.jsx("div",{className:"text-[var(--text-muted)]",children:"Loading autopilot config..."}):e.jsxs("div",{className:"space-y-6",children:[e.jsx(c,{title:"Autopilot",breadcrumbs:[{label:"Admin",href:"/overview"},{label:"Agent"},{label:"Autopilot"}]}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[e.jsxs("div",{className:"bg-[var(--bg-secondary)] border border-[var(--border)] rounded-lg p-4",children:[e.jsx("p",{className:"text-sm text-[var(--text-muted)]",children:"Mode"}),e.jsx("p",{className:"text-lg font-semibold text-[var(--text)] capitalize",children:t==null?void 0:t.mode})]}),e.jsxs("div",{className:"bg-[var(--bg-secondary)] border border-[var(--border)] rounded-lg p-4",children:[e.jsx("p",{className:"text-sm text-[var(--text-muted)]",children:"Interval"}),e.jsx("p",{className:"text-lg font-semibold text-[var(--text)]",children:t!=null&&t.interval?`${Math.round(t.interval/6e4)} min`:"Not set"})]})]}),e.jsx("div",{className:"bg-[var(--bg-secondary)] border border-[var(--border)] rounded-lg p-4",children:e.jsx("p",{className:"text-sm text-[var(--text-muted)]",children:"Autopilot mode enables TITAN to run scheduled tasks automatically. Configure via titan.json."})})]})}export{p as default};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as q,r as p,b as T,j as e,az as O}from"./index-
|
|
1
|
+
import{c as q,r as p,b as T,j as e,az as O}from"./index-CahJbWSR.js";import{o as A,R as W,C as B}from"./TitanCanvas-C-s0A-lv.js";import{P as D}from"./play-CcJ9BnCh.js";import{P as H}from"./pause-DCV52koX.js";import{T as G}from"./trophy-uQv_NgDB.js";import{T as U}from"./trending-up-DGjFyubC.js";import{a as V,C as J}from"./VoiceOverlay-CmNCrLcd.js";/**
|
|
2
2
|
* @license lucide-react v0.513.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as s,aH as p,j as e,aI as u,aJ as h}from"./index-
|
|
1
|
+
import{r as s,aH as p,j as e,aI as u,aJ as h}from"./index-CahJbWSR.js";import{P as g}from"./PageHeader-BimceqQo.js";import{P as b,R as y,A as j}from"./TitanCanvas-C-s0A-lv.js";import{C as v}from"./circle-check-big-DZRE_MbN.js";import"./VoiceOverlay-CmNCrLcd.js";function S(){const[i,x]=s.useState([]),[c,r]=s.useState(!0),[l,n]=s.useState(!1),[d,o]=s.useState(null),t=s.useCallback(async()=>{r(!0);try{const a=await p();x(a.backups||[])}catch{}r(!1)},[]);s.useEffect(()=>{t()},[t]);const m=async()=>{n(!0);try{await u(),await t()}catch{}n(!1)},f=async a=>{o(a);try{await h(a),alert("Backup verified successfully")}catch{alert("Backup verification failed")}o(null)};return e.jsxs("div",{className:"space-y-4",children:[e.jsx(g,{title:"Backup Manager",breadcrumbs:[{label:"Admin",href:"/overview"},{label:"System"},{label:"Backups"}]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("button",{onClick:m,disabled:l,className:"flex items-center gap-2 px-3 py-2 rounded-lg bg-[#6366f1] text-white text-sm font-medium hover:bg-[#4f46e5] disabled:opacity-50",children:[e.jsx(b,{className:"w-4 h-4"})," ",l?"Creating...":"Create Backup"]}),e.jsxs("button",{onClick:t,disabled:c,className:"flex items-center gap-2 px-3 py-2 rounded-lg bg-[#27272a] text-[#a1a1aa] text-sm font-medium hover:bg-[#3f3f46] disabled:opacity-50",children:[e.jsx(y,{className:`w-4 h-4 ${c?"animate-spin":""}`})," Refresh"]})]}),i.length===0&&!c&&e.jsx("div",{className:"text-sm text-[#52525b]",children:"No backups found."}),e.jsx("div",{className:"space-y-2",children:i.map(a=>e.jsxs("div",{className:"flex items-center justify-between p-3 rounded-lg bg-[#0a0a0f] border border-[#27272a]",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(j,{className:"w-4 h-4 text-[#6366f1]"}),e.jsxs("div",{children:[e.jsx("div",{className:"text-sm text-[#e4e4e7]",children:new Date(a.createdAt).toLocaleString()}),e.jsxs("div",{className:"text-xs text-[#52525b]",children:[(a.sizeBytes/1024/1024).toFixed(1)," MB"]})]})]}),e.jsxs("button",{onClick:()=>f(a.path),disabled:d===a.path,className:"flex items-center gap-1.5 px-2.5 py-1.5 rounded-md bg-[#27272a] text-[#a1a1aa] text-xs hover:bg-[#3f3f46] disabled:opacity-50",children:[e.jsx(v,{className:"w-3.5 h-3.5"})," ",d===a.path?"Verifying...":"Verify"]})]},a.path))})]})}export{S as default};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as i,r as s,j as e,G as m,a$ as p}from"./index-
|
|
1
|
+
import{c as i,r as s,j as e,G as m,a$ as p}from"./index-CahJbWSR.js";import{P as h}from"./PageHeader-BimceqQo.js";import"./VoiceOverlay-CmNCrLcd.js";/**
|
|
2
2
|
* @license lucide-react v0.513.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r,bb as m,j as e,aA as p,X as u,b as h}from"./index-
|
|
1
|
+
import{r,bb as m,j as e,aA as p,X as u,b as h}from"./index-CahJbWSR.js";import"./Input-GTHp2Rkr.js";import{S as j}from"./StatusBadge-BtfSPoW2.js";import{P as f}from"./PageHeader-BimceqQo.js";import{E as g}from"./EmptyState-CcKyk5Yn.js";import{S as b}from"./SkeletonLoader-atQtpcF5.js";import{U as N}from"./TitanCanvas-C-s0A-lv.js";import"./VoiceOverlay-CmNCrLcd.js";function y(a){const s=Math.floor((Date.now()-new Date(a).getTime())/1e3);return s<60?`${s}s`:s<3600?`${Math.floor(s/60)}m`:s<86400?`${Math.floor(s/3600)}h`:`${Math.floor(s/86400)}d`}function v(a){const s=a.split("/");return s[s.length-1]}function D(){const[a,s]=r.useState([]),[c,d]=r.useState(!0),[o,l]=r.useState(null),i=r.useCallback(async()=>{try{const t=await m();s(t),l(null)}catch(t){l(t instanceof Error?t.message:"Failed to load agents")}d(!1)},[]);r.useEffect(()=>{i()},[i]);const x=async(t,n)=>{n.preventDefault(),n.stopPropagation();try{await h(`/api/command-post/agents/${t}`,{method:"DELETE"}),await i()}catch{}};return e.jsxs("div",{className:"space-y-4",children:[e.jsx(f,{title:"Agents",breadcrumbs:[{label:"Command Post"},{label:"Agents"}]}),c&&e.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3",children:e.jsx(b,{variant:"card",count:6})}),o&&e.jsx("div",{className:"text-center py-8 text-error text-sm",children:o}),!c&&!o&&a.length===0&&e.jsx(g,{icon:e.jsx(N,{size:32}),title:"No agents registered",description:"Agents will appear here once they connect to Command Post."}),!c&&!o&&a.length>0&&e.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3",children:a.map(t=>e.jsxs(p,{to:`/command-post/agents/${t.id}`,className:"relative bg-bg-secondary border border-border rounded-xl p-4 hover:border-border-light transition-colors group",children:[t.role!=="ceo"&&e.jsx("button",{onClick:n=>x(t.id,n),className:"absolute top-3 right-3 p-1 rounded-md text-text-muted hover:text-error hover:bg-error/10 opacity-0 group-hover:opacity-100 transition-all",title:"Remove agent",children:e.jsx(u,{size:14})}),e.jsxs("div",{className:"flex items-center gap-2 mb-3",children:[e.jsx("span",{className:"text-sm font-semibold text-text",children:t.name}),e.jsx(j,{status:t.status,size:"sm"})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-[10px] text-text-muted uppercase",children:"Role"}),e.jsx("span",{className:"text-xs text-text-secondary capitalize",children:t.role})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-[10px] text-text-muted uppercase",children:"Model"}),e.jsx("span",{className:"text-xs text-text-secondary truncate max-w-[140px]",children:v(t.model)})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-[10px] text-text-muted uppercase",children:"Last Heartbeat"}),e.jsxs("span",{className:"text-xs text-text-secondary",children:[y(t.lastHeartbeat)," ago"]})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-[10px] text-text-muted uppercase",children:"Tasks Done"}),e.jsx("span",{className:"text-xs text-text-secondary",children:t.totalTasksCompleted})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-[10px] text-text-muted uppercase",children:"Cost"}),e.jsxs("span",{className:"text-xs text-text-secondary",children:["$",t.totalCostUsd.toFixed(4)]})]})]})]},t.id))})]})}export{D as default};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as se,r as g,j as t,q as le,bo as ae,bc as re,ba as oe,A as _,aA as q}from"./index-
|
|
1
|
+
import{c as se,r as g,j as t,q as le,bo as ae,bc as re,ba as oe,A as _,aA as q}from"./index-CahJbWSR.js";import"./Input-GTHp2Rkr.js";import{S as ie}from"./StatusBadge-BtfSPoW2.js";import{P as G}from"./PageHeader-BimceqQo.js";import{S as ne}from"./SkeletonLoader-atQtpcF5.js";import{R as ce,U as de}from"./TitanCanvas-C-s0A-lv.js";import{D as xe}from"./dollar-sign-aVG3a5eL.js";import{T as me}from"./target-DWcmM_9m.js";import"./VoiceOverlay-CmNCrLcd.js";/**
|
|
2
2
|
* @license lucide-react v0.513.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as i,j as e,b as f,X as j}from"./index-
|
|
1
|
+
import{r as i,j as e,b as f,X as j}from"./index-CahJbWSR.js";import{s as N,o as y,a as v,R as p,F as w}from"./TitanCanvas-C-s0A-lv.js";import"./VoiceOverlay-CmNCrLcd.js";async function h(t){const a=await f(t);if(!a.ok)throw new Error(`HTTP ${a.status}`);return a.json()}function b(t){return t===void 0?"—":t<1024?`${t}B`:t<1024*1024?`${(t/1024).toFixed(1)}K`:`${(t/1024/1024).toFixed(1)}M`}function g(t){const a=Math.floor((Date.now()-new Date(t).getTime())/1e3);return a<60?`${a}s`:a<3600?`${Math.floor(a/60)}m`:a<86400?`${Math.floor(a/3600)}h`:`${Math.floor(a/86400)}d`}function k({path:t,onClose:a}){const[r,c]=i.useState(null);return i.useEffect(()=>{c(null),h(`/api/files/content?path=${encodeURIComponent(t)}`).then(l=>c(l)).catch(l=>c({error:String(l)}))},[t]),e.jsx("div",{className:"fixed inset-0 z-50 bg-black/60 flex items-center justify-center p-4",onClick:a,children:e.jsxs("div",{className:"bg-bg-secondary border border-border rounded-xl w-full max-w-5xl max-h-[90vh] flex flex-col shadow-2xl",onClick:l=>l.stopPropagation(),children:[e.jsxs("div",{className:"flex items-center justify-between px-4 py-3 border-b border-border",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("div",{className:"text-sm font-medium text-text truncate",children:t}),r&&"sizeBytes"in r&&e.jsxs("div",{className:"text-xs text-text-muted",children:[b(r.sizeBytes)," · ",r.encoding,r.truncated?" · truncated at 1MB":""]})]}),e.jsx("button",{onClick:a,className:"p-1 rounded hover:bg-bg-tertiary text-text-muted",title:"Close",children:e.jsx(j,{size:18})})]}),e.jsxs("div",{className:"flex-1 overflow-auto p-4",children:[r===null&&e.jsx("div",{className:"text-center py-12 text-text-muted text-sm",children:"Loading…"}),r&&"error"in r&&e.jsx("div",{className:"text-error text-sm py-8 text-center",children:r.error}),r&&"content"in r&&e.jsx("pre",{className:"text-[12px] font-mono leading-snug whitespace-pre-wrap text-text-secondary",children:r.content})]})]})})}function C(){const[t,a]=i.useState([]),[r,c]=i.useState(!0),[l,m]=i.useState(""),[o,n]=i.useState(null),d=i.useCallback(async()=>{c(!0);try{const s=await h("/api/files/edited?limit=300");a(s.files||[])}catch{}c(!1)},[]);i.useEffect(()=>{d()},[d]);const x=l?t.filter(s=>s.path.toLowerCase().includes(l.toLowerCase())):t;return e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("div",{className:"flex-1 flex items-center gap-2 px-3 py-1.5 rounded-lg border border-border bg-bg-secondary",children:[e.jsx(v,{size:14,className:"text-text-muted"}),e.jsx("input",{type:"text",placeholder:"Filter by path…",value:l,onChange:s=>m(s.target.value),className:"flex-1 bg-transparent text-sm outline-none"})]}),e.jsxs("button",{onClick:d,className:"px-3 py-1.5 rounded-lg border border-border bg-bg-secondary text-sm hover:bg-bg-tertiary flex items-center gap-1.5",title:"Refresh",children:[e.jsx(p,{size:14,className:r?"animate-spin":""}),r?"Loading":"Refresh"]}),e.jsxs("div",{className:"text-xs text-text-muted",children:[x.length," / ",t.length]})]}),r&&t.length===0&&e.jsx("div",{className:"text-center py-12 text-text-muted text-sm",children:"Loading…"}),!r&&x.length===0&&e.jsx("div",{className:"text-center py-12 text-text-muted text-sm",children:l?"No files match filter":"No file edits recorded yet"}),x.length>0&&e.jsx("div",{className:"divide-y divide-border rounded-xl border border-border bg-bg-secondary overflow-hidden",children:x.map(s=>e.jsxs("button",{onClick:()=>s.readable&&s.exists&&n(s.path),disabled:!s.readable||!s.exists,className:"w-full flex items-start gap-3 px-4 py-2.5 text-left hover:bg-bg-tertiary transition-colors disabled:opacity-50 disabled:cursor-not-allowed",children:[e.jsx(w,{size:14,className:s.isSelfMod?"text-accent mt-0.5 flex-shrink-0":"text-text-muted mt-0.5 flex-shrink-0"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("div",{className:"text-sm font-mono text-text truncate",children:s.path}),e.jsxs("div",{className:"text-xs text-text-muted mt-0.5 flex items-center gap-2 flex-wrap",children:[s.isSelfMod&&e.jsx("span",{className:"px-1 rounded bg-accent/15 text-accent text-[10px]",children:"self-mod"}),e.jsxs("span",{children:["×",s.writeCount]}),s.tools.length>0&&e.jsx("span",{children:s.tools.join("+")}),s.channels.length>0&&e.jsxs("span",{children:["via ",s.channels.join(", ")]}),!s.exists&&e.jsx("span",{className:"text-warn",children:"deleted"}),e.jsx("span",{children:b(s.sizeBytes)})]})]}),e.jsx("div",{className:"text-xs text-text-muted flex-shrink-0",children:g(s.lastWrittenAt)})]},s.path))}),o&&e.jsx(k,{path:o,onClose:()=>n(null)})]})}function S(){const[t,a]=i.useState([]),[r,c]=i.useState(!0),[l,m]=i.useState(null),o=i.useCallback(async()=>{c(!0);try{const n=await h("/api/research/recent?limit=50");a(n.research||[])}catch{}c(!1)},[]);return i.useEffect(()=>{o()},[o]),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("button",{onClick:o,className:"px-3 py-1.5 rounded-lg border border-border bg-bg-secondary text-sm hover:bg-bg-tertiary flex items-center gap-1.5",children:[e.jsx(p,{size:14,className:r?"animate-spin":""}),r?"Loading":"Refresh"]}),e.jsxs("div",{className:"text-xs text-text-muted",children:[t.length," items"]})]}),r&&t.length===0&&e.jsx("div",{className:"text-center py-12 text-text-muted text-sm",children:"Loading…"}),!r&&t.length===0&&e.jsx("div",{className:"text-center py-12 text-text-muted text-sm",children:"No research recorded yet. Complete a goal and results will appear here."}),e.jsx("div",{className:"space-y-2",children:t.map(n=>{var u;const d=l===n.id,x=n.content.slice(0,200),s=n.subtaskTitle?`${n.goalTitle} — ${n.subtaskTitle}`:((u=n.tags)==null?void 0:u.join(" · "))||n.kind;return e.jsxs("div",{className:"rounded-xl border border-border bg-bg-secondary overflow-hidden",children:[e.jsxs("button",{onClick:()=>m(d?null:n.id),className:"w-full text-left px-4 py-3 hover:bg-bg-tertiary transition-colors",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx("span",{className:"text-[10px] px-1.5 py-0.5 rounded bg-bg-tertiary text-text-muted uppercase tracking-wide font-medium",children:n.kind.replace(/_/g," ")}),e.jsx("span",{className:"text-xs text-text-muted",children:g(n.at)})]}),e.jsx("div",{className:"text-sm font-medium text-text truncate",children:s}),!d&&e.jsxs("div",{className:"text-xs text-text-secondary mt-1 line-clamp-2",children:[x,n.content.length>200?"…":""]})]}),d&&e.jsx("div",{className:"px-4 pb-4",children:e.jsx("pre",{className:"text-[12px] font-mono leading-snug whitespace-pre-wrap text-text-secondary",children:n.content})})]},n.id)})})]})}function T(){const[t,a]=i.useState("files");return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("button",{onClick:()=>a("files"),className:`flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-sm transition-colors ${t==="files"?"bg-accent/15 text-accent border border-accent/30":"text-text-secondary hover:text-text hover:bg-bg-tertiary border border-transparent"}`,children:[e.jsx(N,{size:14})," Files edited"]}),e.jsxs("button",{onClick:()=>a("research"),className:`flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-sm transition-colors ${t==="research"?"bg-accent/15 text-accent border border-accent/30":"text-text-secondary hover:text-text hover:bg-bg-tertiary border border-transparent"}`,children:[e.jsx(y,{size:14})," Research"]})]}),t==="files"?e.jsx(C,{}):e.jsx(S,{})]})}export{T as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as i,bp as D,j as e,X as $,b as N}from"./index-
|
|
1
|
+
import{r as i,bp as D,j as e,X as $,b as N}from"./index-CahJbWSR.js";import{B as j}from"./Input-GTHp2Rkr.js";import{S as T}from"./StatusBadge-BtfSPoW2.js";import{P as M}from"./PageHeader-BimceqQo.js";import{E as O}from"./EmptyState-CcKyk5Yn.js";import{M as A}from"./CommandPostHub-BgxIa4Ev.js";import{S as F}from"./SkeletonLoader-atQtpcF5.js";import{P as L}from"./TitanCanvas-C-s0A-lv.js";import{T as y}from"./target-DWcmM_9m.js";import{a as B,C as I}from"./VoiceOverlay-CmNCrLcd.js";import{T as U}from"./trash-2-CK7yQ55V.js";import"./proxy-CzZDfLmm.js";import"./InlineEditableField-CnvF-yFR.js";import"./Tooltip-70UK0E2I.js";import"./pause-DCV52koX.js";import"./dollar-sign-aVG3a5eL.js";import"./git-branch-BM-Gw95X.js";import"./chart-column-BtNO6sRy.js";function _(t){const a=Math.floor((Date.now()-new Date(t).getTime())/1e3);return a<60?`${a}s`:a<3600?`${Math.floor(a/60)}m`:a<86400?`${Math.floor(a/3600)}h`:`${Math.floor(a/86400)}d`}const H=["pending","in_progress","completed","blocked"];function J({node:t,onClose:a,onRefresh:l}){const[d,c]=i.useState(!1),[x,m]=i.useState(!1),r=t.goal,g=async()=>{c(!0);try{await N(`/api/goals/${r.id}`,{method:"DELETE"}),l(),a()}catch{}c(!1)},o=async n=>{m(!0);try{await N(`/api/goals/${r.id}`,{method:"PATCH",body:JSON.stringify({status:n})}),l()}catch{}m(!1)};return e.jsxs("div",{className:"bg-bg-secondary border border-border rounded-xl p-5 space-y-4",children:[e.jsxs("div",{className:"flex items-start justify-between",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx("h3",{className:"text-lg font-semibold text-text",children:r.title}),r.description&&e.jsx("p",{className:"text-sm text-text-secondary mt-1",children:r.description})]}),e.jsx("button",{onClick:a,className:"p-1 text-text-muted hover:text-text rounded-lg hover:bg-bg-tertiary transition-colors",children:e.jsx($,{size:16})})]}),e.jsxs("div",{className:"flex flex-wrap gap-3 text-xs",children:[e.jsxs("div",{className:"bg-bg-tertiary/50 rounded-lg px-3 py-2",children:[e.jsx("span",{className:"text-text-muted",children:"Status: "}),e.jsx(T,{status:r.status,size:"sm"})]}),r.progress>0&&e.jsxs("div",{className:"bg-bg-tertiary/50 rounded-lg px-3 py-2",children:[e.jsx("span",{className:"text-text-muted",children:"Progress: "}),e.jsxs("span",{className:"text-text font-medium",children:[Math.round(r.progress),"%"]})]}),t.children.length>0&&e.jsxs("div",{className:"bg-bg-tertiary/50 rounded-lg px-3 py-2",children:[e.jsx("span",{className:"text-text-muted",children:"Sub-goals: "}),e.jsxs("span",{className:"text-text font-medium",children:[t.children.filter(n=>n.goal.status==="completed"||n.goal.status==="done").length,"/",t.children.length," done"]})]}),e.jsxs("div",{className:"bg-bg-tertiary/50 rounded-lg px-3 py-2",children:[e.jsx("span",{className:"text-text-muted",children:"Updated: "}),e.jsxs("span",{className:"text-text font-medium",children:[_(r.updatedAt||r.createdAt||new Date().toISOString())," ago"]})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs text-text-muted mb-2",children:"Change Status"}),e.jsx("div",{className:"flex gap-2 flex-wrap",children:H.map(n=>e.jsx("button",{disabled:x||r.status===n,onClick:()=>o(n),className:`px-3 py-1.5 rounded-lg text-xs font-medium transition-colors ${r.status===n?"bg-accent/20 text-accent border border-accent/30":"bg-bg-tertiary text-text-secondary hover:bg-bg-tertiary/80 border border-border"} disabled:opacity-50`,children:n.replace("_"," ")},n))})]}),e.jsx("div",{className:"pt-2 border-t border-border flex justify-end",children:e.jsxs("button",{onClick:g,disabled:d,className:"flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-xs font-medium text-error hover:bg-error/10 transition-colors disabled:opacity-50",children:[e.jsx(U,{size:12}),d?"Deleting...":"Delete Goal"]})})]})}function z({node:t,expanded:a,toggleExpand:l,selectedId:d,onSelect:c}){const x=t.children.length>0,m=a.has(t.goal.id),r=d===t.goal.id,g=t.children.filter(o=>o.goal.status==="completed"||o.goal.status==="done").length;return e.jsxs("div",{children:[e.jsxs("div",{className:`flex items-center gap-2 py-2 px-3 rounded-lg transition-colors cursor-pointer group ${r?"bg-accent/10 border-l-2 border-accent":"hover:bg-bg-tertiary/50"}`,style:{paddingLeft:`${t.depth*24+12}px`},onClick:()=>c(t),children:[x?e.jsx("button",{onClick:o=>{o.stopPropagation(),l(t.goal.id)},className:"p-0.5 rounded hover:bg-bg-tertiary transition-colors",children:m?e.jsx(B,{size:14,className:"text-text-muted"}):e.jsx(I,{size:14,className:"text-text-muted"})}):e.jsx("span",{className:"w-[18px] flex-shrink-0"}),e.jsx(y,{size:14,className:r?"text-accent":"text-text-muted"}),e.jsx("span",{className:"text-sm text-text flex-1 truncate",children:t.goal.title}),e.jsx(T,{status:t.goal.status,size:"sm"}),x&&e.jsxs("span",{className:"text-[10px] text-text-muted",children:[g,"/",t.children.length]}),t.goal.progress>0&&e.jsx("div",{className:"w-16 h-1.5 bg-bg-tertiary rounded-full overflow-hidden flex-shrink-0",children:e.jsx("div",{className:"h-full bg-accent rounded-full transition-all",style:{width:`${Math.min(100,t.goal.progress)}%`}})})]}),x&&m&&e.jsx("div",{children:t.children.map(o=>e.jsx(z,{node:o,expanded:a,toggleExpand:l,selectedId:d,onSelect:c},o.goal.id))})]})}function E(t,a){for(const l of t){if(l.goal.id===a)return l;const d=E(l.children,a);if(d)return d}return null}function de(){const[t,a]=i.useState([]),[l,d]=i.useState(!0),[c,x]=i.useState(null),[m,r]=i.useState(new Set),[g,o]=i.useState(null),[n,u]=i.useState(!1),[p,v]=i.useState(""),[P,S]=i.useState(!1),b=i.useCallback(async()=>{try{const s=await D();a(s),r(new Set(s.map(h=>h.goal.id))),x(null)}catch(s){x(s instanceof Error?s.message:"Failed to load goals")}d(!1)},[]);i.useEffect(()=>{b()},[b]);const C=s=>{r(h=>{const f=new Set(h);return f.has(s)?f.delete(s):f.add(s),f})},G=s=>{o(h=>h===s.goal.id?null:s.goal.id),s.children.length>0&&!m.has(s.goal.id)&&C(s.goal.id)},w=async()=>{if(p.trim()){S(!0);try{await N("/api/command-post/goals",{method:"POST",body:JSON.stringify({title:p.trim()})}),u(!1),v(""),await b()}catch{}S(!1)}},k=g?E(t,g):null;return e.jsxs("div",{className:"space-y-4",children:[e.jsx(M,{title:"Goals",breadcrumbs:[{label:"Command Post"},{label:"Goals"}],actions:e.jsx(j,{size:"sm",icon:e.jsx(L,{size:14}),onClick:()=>u(!0),children:"Create Goal"})}),l&&e.jsx(F,{variant:"row",count:5}),c&&e.jsx("div",{className:"text-center py-8 text-error text-sm",children:c}),!l&&!c&&t.length===0&&e.jsx(O,{icon:e.jsx(y,{size:32}),title:"No goals",description:"Create your first goal to start organizing agent work.",action:{label:"Create Goal",onClick:()=>u(!0)}}),!l&&!c&&t.length>0&&e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-3 gap-4",children:[e.jsxs("div",{className:"lg:col-span-2 rounded-xl border border-border bg-bg-secondary overflow-hidden",children:[e.jsxs("div",{className:"px-4 py-3 border-b border-border flex items-center justify-between",children:[e.jsxs("span",{className:"text-xs text-text-muted",children:[t.length," top-level goal",t.length!==1?"s":""]}),e.jsx("span",{className:"text-[10px] text-text-muted",children:"Click a goal to view details"})]}),e.jsx("div",{className:"divide-y divide-border",children:t.map(s=>e.jsx(z,{node:s,expanded:m,toggleExpand:C,selectedId:g,onSelect:G},s.goal.id))})]}),e.jsx("div",{className:"lg:col-span-1",children:k?e.jsx(J,{node:k,onClose:()=>o(null),onRefresh:b}):e.jsxs("div",{className:"bg-bg-secondary border border-border rounded-xl p-8 text-center",children:[e.jsx(y,{size:24,className:"text-text-muted mx-auto mb-2"}),e.jsx("p",{className:"text-xs text-text-muted",children:"Select a goal to view details"})]})})]}),e.jsx(A,{open:n,onClose:()=>u(!1),title:"Create Goal",footer:e.jsxs(e.Fragment,{children:[e.jsx(j,{variant:"secondary",size:"sm",onClick:()=>u(!1),children:"Cancel"}),e.jsx(j,{size:"sm",onClick:w,loading:P,disabled:!p.trim(),children:"Create"})]}),children:e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs text-text-muted mb-1",children:"Goal Title"}),e.jsx("input",{className:"w-full rounded-lg border border-border bg-bg-tertiary px-3 py-2 text-sm text-text placeholder:text-text-muted focus:outline-none focus:border-accent",placeholder:"Enter goal title...",value:p,onChange:s=>v(s.target.value),onKeyDown:s=>s.key==="Enter"&&w(),autoFocus:!0})]})})]})}export{de as default};
|