@integrity-labs/agt-cli 0.27.7-test.5 → 0.27.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/impersonate-statusline.sh +88 -0
- package/dist/bin/agt.js +221 -83
- package/dist/bin/agt.js.map +1 -1
- package/dist/{chunk-WCY7QM3R.js → chunk-IB655E5U.js} +1 -1
- package/dist/lib/manager-worker.js +2 -2
- package/dist/lib/manager-worker.js.map +1 -1
- package/package.json +3 -2
- /package/dist/{chunk-WCY7QM3R.js.map → chunk-IB655E5U.js.map} +0 -0
package/dist/bin/agt.js
CHANGED
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
success,
|
|
28
28
|
table,
|
|
29
29
|
warn
|
|
30
|
-
} from "../chunk-
|
|
30
|
+
} from "../chunk-IB655E5U.js";
|
|
31
31
|
import {
|
|
32
32
|
CHANNEL_REGISTRY,
|
|
33
33
|
DEPLOYMENT_TEMPLATES,
|
|
@@ -56,8 +56,8 @@ import {
|
|
|
56
56
|
} from "../chunk-YSBGIXJG.js";
|
|
57
57
|
|
|
58
58
|
// src/bin/agt.ts
|
|
59
|
-
import { join as
|
|
60
|
-
import { homedir as
|
|
59
|
+
import { join as join15 } from "path";
|
|
60
|
+
import { homedir as homedir6 } from "os";
|
|
61
61
|
import { Command } from "commander";
|
|
62
62
|
|
|
63
63
|
// src/commands/whoami.ts
|
|
@@ -551,8 +551,8 @@ async function lintCommand(path) {
|
|
|
551
551
|
process.exitCode = 1;
|
|
552
552
|
return;
|
|
553
553
|
}
|
|
554
|
-
const { readdirSync:
|
|
555
|
-
const entries =
|
|
554
|
+
const { readdirSync: readdirSync3, statSync: statSync2 } = await import("fs");
|
|
555
|
+
const entries = readdirSync3(augmentedDir);
|
|
556
556
|
for (const entry of entries) {
|
|
557
557
|
const entryPath = join2(augmentedDir, entry);
|
|
558
558
|
if (statSync2(entryPath).isDirectory()) {
|
|
@@ -1557,8 +1557,8 @@ async function provisionCommand(codeName, options) {
|
|
|
1557
1557
|
import chalk10 from "chalk";
|
|
1558
1558
|
import ora10 from "ora";
|
|
1559
1559
|
import { spawn } from "child_process";
|
|
1560
|
-
import { readFileSync as
|
|
1561
|
-
import { join as
|
|
1560
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync7 } from "fs";
|
|
1561
|
+
import { join as join10 } from "path";
|
|
1562
1562
|
|
|
1563
1563
|
// src/lib/impersonate-flag.ts
|
|
1564
1564
|
var ENV_VAR = "AGT_IMPERSONATE_ENABLED";
|
|
@@ -1844,6 +1844,124 @@ function asPlainObject(value) {
|
|
|
1844
1844
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
1845
1845
|
}
|
|
1846
1846
|
|
|
1847
|
+
// src/lib/impersonate-statusline.ts
|
|
1848
|
+
import {
|
|
1849
|
+
chmodSync as chmodSync2,
|
|
1850
|
+
copyFileSync as copyFileSync2,
|
|
1851
|
+
existsSync as existsSync5,
|
|
1852
|
+
mkdirSync as mkdirSync6,
|
|
1853
|
+
readdirSync as readdirSync2,
|
|
1854
|
+
readFileSync as readFileSync4,
|
|
1855
|
+
renameSync as renameSync4,
|
|
1856
|
+
rmdirSync as rmdirSync2,
|
|
1857
|
+
unlinkSync as unlinkSync3,
|
|
1858
|
+
writeFileSync as writeFileSync6
|
|
1859
|
+
} from "fs";
|
|
1860
|
+
import { homedir as homedir3 } from "os";
|
|
1861
|
+
import { dirname as dirname2, join as join9 } from "path";
|
|
1862
|
+
import { fileURLToPath } from "url";
|
|
1863
|
+
var INSTALLED_STATUSLINE_PATH = join9(
|
|
1864
|
+
homedir3(),
|
|
1865
|
+
".augmented-impersonate",
|
|
1866
|
+
"statusline.sh"
|
|
1867
|
+
);
|
|
1868
|
+
var STATUS_LINE_KEY = "statusLine";
|
|
1869
|
+
var STATUS_LINE_COMMAND_TYPE = "command";
|
|
1870
|
+
function installStatusLineAsset(targetPath = INSTALLED_STATUSLINE_PATH) {
|
|
1871
|
+
mkdirSync6(dirname2(targetPath), { recursive: true });
|
|
1872
|
+
const source = resolveBundledAssetPath();
|
|
1873
|
+
const needsCopy = !existsSync5(targetPath) || readFileSync4(source, "utf-8") !== readFileSync4(targetPath, "utf-8");
|
|
1874
|
+
if (needsCopy) {
|
|
1875
|
+
copyFileSync2(source, targetPath);
|
|
1876
|
+
chmodSync2(targetPath, 493);
|
|
1877
|
+
}
|
|
1878
|
+
}
|
|
1879
|
+
function registerStatusLine(projectCwd, options = {}) {
|
|
1880
|
+
if (options.installAsset !== false) {
|
|
1881
|
+
installStatusLineAsset();
|
|
1882
|
+
}
|
|
1883
|
+
const claudeDir = join9(projectCwd, ".claude");
|
|
1884
|
+
const createdClaudeDir = !existsSync5(claudeDir);
|
|
1885
|
+
mkdirSync6(claudeDir, { recursive: true });
|
|
1886
|
+
const settingsPath = join9(claudeDir, "settings.local.json");
|
|
1887
|
+
const settingsExisted = existsSync5(settingsPath);
|
|
1888
|
+
const backupPath = settingsPath + BACKUP_SUFFIX;
|
|
1889
|
+
let settings = {};
|
|
1890
|
+
if (settingsExisted) {
|
|
1891
|
+
if (!existsSync5(backupPath)) {
|
|
1892
|
+
copyFileSync2(settingsPath, backupPath);
|
|
1893
|
+
}
|
|
1894
|
+
settings = asPlainObject2(safeParseJson2(readFileSync4(settingsPath, "utf-8")));
|
|
1895
|
+
}
|
|
1896
|
+
settings[STATUS_LINE_KEY] = {
|
|
1897
|
+
type: STATUS_LINE_COMMAND_TYPE,
|
|
1898
|
+
command: INSTALLED_STATUSLINE_PATH
|
|
1899
|
+
};
|
|
1900
|
+
writeFileSync6(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
1901
|
+
return {
|
|
1902
|
+
settings_path: settingsPath,
|
|
1903
|
+
settings_backup: settingsExisted ? "had-file" : "didnt-exist",
|
|
1904
|
+
created_claude_dir: createdClaudeDir
|
|
1905
|
+
};
|
|
1906
|
+
}
|
|
1907
|
+
function unregisterStatusLine(backup) {
|
|
1908
|
+
const { settings_path, settings_backup, created_claude_dir } = backup;
|
|
1909
|
+
const backupPath = settings_path + BACKUP_SUFFIX;
|
|
1910
|
+
if (settings_backup === "had-file") {
|
|
1911
|
+
if (existsSync5(backupPath)) {
|
|
1912
|
+
renameSync4(backupPath, settings_path);
|
|
1913
|
+
} else if (existsSync5(settings_path)) {
|
|
1914
|
+
stripStatusLineKey(settings_path);
|
|
1915
|
+
}
|
|
1916
|
+
} else {
|
|
1917
|
+
if (existsSync5(settings_path)) unlinkSync3(settings_path);
|
|
1918
|
+
if (existsSync5(backupPath)) unlinkSync3(backupPath);
|
|
1919
|
+
}
|
|
1920
|
+
if (created_claude_dir) {
|
|
1921
|
+
const claudeDir = dirname2(settings_path);
|
|
1922
|
+
try {
|
|
1923
|
+
if (existsSync5(claudeDir) && readdirSync2(claudeDir).length === 0) {
|
|
1924
|
+
rmdirSync2(claudeDir);
|
|
1925
|
+
}
|
|
1926
|
+
} catch {
|
|
1927
|
+
}
|
|
1928
|
+
}
|
|
1929
|
+
}
|
|
1930
|
+
function resolveBundledAssetPath() {
|
|
1931
|
+
const moduleDir = dirname2(fileURLToPath(import.meta.url));
|
|
1932
|
+
const candidates = [
|
|
1933
|
+
// Built output: dist/<chunk>.js → dist/assets/...
|
|
1934
|
+
join9(moduleDir, "assets", "impersonate-statusline.sh"),
|
|
1935
|
+
// Built output sibling case: dist/<sub>/<chunk>.js → dist/assets/...
|
|
1936
|
+
join9(moduleDir, "..", "assets", "impersonate-statusline.sh"),
|
|
1937
|
+
// Dev source: src/lib/impersonate-statusline.ts → ../../assets/...
|
|
1938
|
+
join9(moduleDir, "..", "..", "assets", "impersonate-statusline.sh")
|
|
1939
|
+
];
|
|
1940
|
+
for (const candidate of candidates) {
|
|
1941
|
+
if (existsSync5(candidate)) return candidate;
|
|
1942
|
+
}
|
|
1943
|
+
throw new Error(
|
|
1944
|
+
`[impersonate-statusline] could not locate bundled asset; tried:
|
|
1945
|
+
${candidates.join("\n ")}`
|
|
1946
|
+
);
|
|
1947
|
+
}
|
|
1948
|
+
function stripStatusLineKey(settingsPath) {
|
|
1949
|
+
const settings = asPlainObject2(safeParseJson2(readFileSync4(settingsPath, "utf-8")));
|
|
1950
|
+
if (!(STATUS_LINE_KEY in settings)) return;
|
|
1951
|
+
delete settings[STATUS_LINE_KEY];
|
|
1952
|
+
writeFileSync6(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
1953
|
+
}
|
|
1954
|
+
function safeParseJson2(text) {
|
|
1955
|
+
try {
|
|
1956
|
+
return JSON.parse(text);
|
|
1957
|
+
} catch {
|
|
1958
|
+
return null;
|
|
1959
|
+
}
|
|
1960
|
+
}
|
|
1961
|
+
function asPlainObject2(value) {
|
|
1962
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
1963
|
+
}
|
|
1964
|
+
|
|
1847
1965
|
// src/lib/impersonate-introduce.ts
|
|
1848
1966
|
function parseIdentityFromClaudeMd(content) {
|
|
1849
1967
|
const headingMatch = content.match(/^#\s+(.+?)\s*$/m);
|
|
@@ -1947,12 +2065,12 @@ async function impersonateConnectCommand(token, options = {}) {
|
|
|
1947
2065
|
}
|
|
1948
2066
|
spinner.text = "Writing persona files\u2026";
|
|
1949
2067
|
const personaDir = ensureCodeNameDir(bundle.agent.code_name);
|
|
1950
|
-
|
|
1951
|
-
|
|
2068
|
+
writeFileSync7(
|
|
2069
|
+
join10(personaDir, "CLAUDE.md"),
|
|
1952
2070
|
bundle.artifacts["CLAUDE.md"]
|
|
1953
2071
|
);
|
|
1954
|
-
|
|
1955
|
-
|
|
2072
|
+
writeFileSync7(
|
|
2073
|
+
join10(personaDir, ".mcp.json"),
|
|
1956
2074
|
bundle.artifacts[".mcp.json"]
|
|
1957
2075
|
);
|
|
1958
2076
|
spinner.text = "Swapping persona files\u2026";
|
|
@@ -1960,14 +2078,16 @@ async function impersonateConnectCommand(token, options = {}) {
|
|
|
1960
2078
|
const backups = {};
|
|
1961
2079
|
const swapped = [];
|
|
1962
2080
|
let hookBackup;
|
|
2081
|
+
let statusLineBackup;
|
|
1963
2082
|
try {
|
|
1964
2083
|
for (const file of SWAP_FILES) {
|
|
1965
|
-
const projectPath =
|
|
1966
|
-
const kind = swapInPersonaFile(projectPath,
|
|
2084
|
+
const projectPath = join10(projectCwd, file);
|
|
2085
|
+
const kind = swapInPersonaFile(projectPath, join10(personaDir, file));
|
|
1967
2086
|
backups[file] = kind;
|
|
1968
2087
|
swapped.push({ file, kind });
|
|
1969
2088
|
}
|
|
1970
2089
|
hookBackup = registerIntroduceHook(projectCwd);
|
|
2090
|
+
statusLineBackup = registerStatusLine(projectCwd);
|
|
1971
2091
|
const manifest = {
|
|
1972
2092
|
code_name: bundle.agent.code_name,
|
|
1973
2093
|
agent_id: bundle.agent.agent_id,
|
|
@@ -1979,10 +2099,17 @@ async function impersonateConnectCommand(token, options = {}) {
|
|
|
1979
2099
|
project_cwd: projectCwd,
|
|
1980
2100
|
host: host2,
|
|
1981
2101
|
backups,
|
|
1982
|
-
hook: hookBackup
|
|
2102
|
+
hook: hookBackup,
|
|
2103
|
+
statusLine: statusLineBackup
|
|
1983
2104
|
};
|
|
1984
2105
|
writeActiveManifest(manifest);
|
|
1985
2106
|
} catch (err) {
|
|
2107
|
+
if (statusLineBackup) {
|
|
2108
|
+
try {
|
|
2109
|
+
unregisterStatusLine(statusLineBackup);
|
|
2110
|
+
} catch {
|
|
2111
|
+
}
|
|
2112
|
+
}
|
|
1986
2113
|
if (hookBackup) {
|
|
1987
2114
|
try {
|
|
1988
2115
|
unregisterIntroduceHook(hookBackup);
|
|
@@ -1991,7 +2118,7 @@ async function impersonateConnectCommand(token, options = {}) {
|
|
|
1991
2118
|
}
|
|
1992
2119
|
for (const { file, kind } of [...swapped].reverse()) {
|
|
1993
2120
|
try {
|
|
1994
|
-
restoreSwapped(
|
|
2121
|
+
restoreSwapped(join10(projectCwd, file), kind);
|
|
1995
2122
|
} catch {
|
|
1996
2123
|
}
|
|
1997
2124
|
}
|
|
@@ -2140,7 +2267,7 @@ async function impersonateExitCommand() {
|
|
|
2140
2267
|
}
|
|
2141
2268
|
const restored = [];
|
|
2142
2269
|
for (const [file, kind] of Object.entries(manifest.backups)) {
|
|
2143
|
-
const projectPath =
|
|
2270
|
+
const projectPath = join10(manifest.project_cwd, file);
|
|
2144
2271
|
try {
|
|
2145
2272
|
restoreSwapped(projectPath, kind);
|
|
2146
2273
|
restored.push(file);
|
|
@@ -2149,6 +2276,17 @@ async function impersonateExitCommand() {
|
|
|
2149
2276
|
if (!json) error(`Failed to restore ${file}: ${msg}`);
|
|
2150
2277
|
}
|
|
2151
2278
|
}
|
|
2279
|
+
if (manifest.statusLine) {
|
|
2280
|
+
try {
|
|
2281
|
+
unregisterStatusLine(manifest.statusLine);
|
|
2282
|
+
} catch (err) {
|
|
2283
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2284
|
+
if (!json) error(`Failed to remove statusLine: ${msg}`);
|
|
2285
|
+
}
|
|
2286
|
+
if (!json && process.stdout.isTTY) {
|
|
2287
|
+
process.stdout.write("\x1B]1;\x07");
|
|
2288
|
+
}
|
|
2289
|
+
}
|
|
2152
2290
|
if (manifest.hook) {
|
|
2153
2291
|
try {
|
|
2154
2292
|
unregisterIntroduceHook(manifest.hook);
|
|
@@ -2183,8 +2321,8 @@ async function impersonateIntroduceCommand() {
|
|
|
2183
2321
|
const manifest = readActiveManifest();
|
|
2184
2322
|
if (!manifest || isExpired(manifest)) return;
|
|
2185
2323
|
const cwd = manifest.project_cwd;
|
|
2186
|
-
const identity = readClaudeMdIdentity(
|
|
2187
|
-
const integrations = readMcpIntegrations(
|
|
2324
|
+
const identity = readClaudeMdIdentity(join10(cwd, "CLAUDE.md"));
|
|
2325
|
+
const integrations = readMcpIntegrations(join10(cwd, ".mcp.json"));
|
|
2188
2326
|
const intro = buildIntroduction({
|
|
2189
2327
|
displayName: identity.displayName,
|
|
2190
2328
|
codeName: manifest.code_name,
|
|
@@ -2197,14 +2335,14 @@ async function impersonateIntroduceCommand() {
|
|
|
2197
2335
|
}
|
|
2198
2336
|
function readClaudeMdIdentity(path) {
|
|
2199
2337
|
try {
|
|
2200
|
-
return parseIdentityFromClaudeMd(
|
|
2338
|
+
return parseIdentityFromClaudeMd(readFileSync5(path, "utf-8"));
|
|
2201
2339
|
} catch {
|
|
2202
2340
|
return { displayName: null, role: null };
|
|
2203
2341
|
}
|
|
2204
2342
|
}
|
|
2205
2343
|
function readMcpIntegrations(path) {
|
|
2206
2344
|
try {
|
|
2207
|
-
return parseIntegrationsFromMcpJson(
|
|
2345
|
+
return parseIntegrationsFromMcpJson(readFileSync5(path, "utf-8"));
|
|
2208
2346
|
} catch {
|
|
2209
2347
|
return [];
|
|
2210
2348
|
}
|
|
@@ -2217,7 +2355,7 @@ import ora11 from "ora";
|
|
|
2217
2355
|
// ../../packages/core/dist/drift/live-state-reader.js
|
|
2218
2356
|
import { readFile } from "fs/promises";
|
|
2219
2357
|
import { createHash } from "crypto";
|
|
2220
|
-
import { join as
|
|
2358
|
+
import { join as join11 } from "path";
|
|
2221
2359
|
import JSON5 from "json5";
|
|
2222
2360
|
async function hashFile(filePath) {
|
|
2223
2361
|
try {
|
|
@@ -2241,8 +2379,8 @@ async function readLiveState(options) {
|
|
|
2241
2379
|
const toolsFile = trackedFiles.find((f) => f.includes("TOOLS")) ?? "TOOLS.md";
|
|
2242
2380
|
const [frameworkConfig, charterHash, toolsHash] = await Promise.all([
|
|
2243
2381
|
readJsonFile(options.configPath),
|
|
2244
|
-
hashFile(
|
|
2245
|
-
hashFile(
|
|
2382
|
+
hashFile(join11(options.teamDir, charterFile)),
|
|
2383
|
+
hashFile(join11(options.teamDir, toolsFile))
|
|
2246
2384
|
]);
|
|
2247
2385
|
return {
|
|
2248
2386
|
frameworkConfig,
|
|
@@ -2851,15 +2989,15 @@ function terminate(child) {
|
|
|
2851
2989
|
// src/commands/manager-watch.tsx
|
|
2852
2990
|
import { useEffect, useState, useMemo } from "react";
|
|
2853
2991
|
import { render, Box, Text, useApp, useInput } from "ink";
|
|
2854
|
-
import { existsSync as
|
|
2855
|
-
import { homedir as
|
|
2856
|
-
import { join as
|
|
2992
|
+
import { existsSync as existsSync6, readFileSync as readFileSync6, statSync, openSync, readSync, closeSync } from "fs";
|
|
2993
|
+
import { homedir as homedir4 } from "os";
|
|
2994
|
+
import { join as join12 } from "path";
|
|
2857
2995
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2858
2996
|
var REFRESH_MS = 1e3;
|
|
2859
2997
|
var LOG_TAIL_LINES = 200;
|
|
2860
2998
|
var DETAIL_RECENT_LINES = 50;
|
|
2861
2999
|
function managerWatchCommand(opts = {}) {
|
|
2862
|
-
const configDir = opts.configDir ??
|
|
3000
|
+
const configDir = opts.configDir ?? join12(homedir4(), ".augmented");
|
|
2863
3001
|
const paths = getManagerPaths(configDir);
|
|
2864
3002
|
const isTty = process.stdout.isTTY === true && process.stdin.isTTY === true;
|
|
2865
3003
|
if (opts.noTui || !isTty) {
|
|
@@ -2883,15 +3021,15 @@ function managerWatchCommand(opts = {}) {
|
|
|
2883
3021
|
}
|
|
2884
3022
|
function readState(stateFile) {
|
|
2885
3023
|
try {
|
|
2886
|
-
if (!
|
|
2887
|
-
const raw =
|
|
3024
|
+
if (!existsSync6(stateFile)) return null;
|
|
3025
|
+
const raw = readFileSync6(stateFile, "utf-8");
|
|
2888
3026
|
return JSON.parse(raw);
|
|
2889
3027
|
} catch {
|
|
2890
3028
|
return null;
|
|
2891
3029
|
}
|
|
2892
3030
|
}
|
|
2893
3031
|
function tailLogFile(logFile, lines) {
|
|
2894
|
-
if (!
|
|
3032
|
+
if (!existsSync6(logFile)) return [];
|
|
2895
3033
|
try {
|
|
2896
3034
|
const fileSize = statSync(logFile).size;
|
|
2897
3035
|
if (fileSize === 0) return [];
|
|
@@ -3132,7 +3270,7 @@ function truncate(s, max) {
|
|
|
3132
3270
|
return s.length > max ? `${s.slice(0, Math.max(0, max - 1))}\u2026` : s;
|
|
3133
3271
|
}
|
|
3134
3272
|
function streamLogFile(logFile) {
|
|
3135
|
-
if (!
|
|
3273
|
+
if (!existsSync6(logFile)) {
|
|
3136
3274
|
process.stderr.write(`No manager log found at ${logFile}.
|
|
3137
3275
|
Start the manager first: agt manager start
|
|
3138
3276
|
`);
|
|
@@ -3141,7 +3279,7 @@ Start the manager first: agt manager start
|
|
|
3141
3279
|
}
|
|
3142
3280
|
let lastSize = 0;
|
|
3143
3281
|
try {
|
|
3144
|
-
const initial =
|
|
3282
|
+
const initial = readFileSync6(logFile, "utf-8");
|
|
3145
3283
|
process.stdout.write(initial);
|
|
3146
3284
|
lastSize = statSync(logFile).size;
|
|
3147
3285
|
} catch (err) {
|
|
@@ -3178,14 +3316,14 @@ Start the manager first: agt manager start
|
|
|
3178
3316
|
// src/commands/agent.ts
|
|
3179
3317
|
import chalk14 from "chalk";
|
|
3180
3318
|
import JSON52 from "json5";
|
|
3181
|
-
import { readFileSync as
|
|
3182
|
-
import { join as
|
|
3319
|
+
import { readFileSync as readFileSync7, existsSync as existsSync7 } from "fs";
|
|
3320
|
+
import { join as join13 } from "path";
|
|
3183
3321
|
async function agentShowCommand(codeName, opts) {
|
|
3184
3322
|
const json = isJsonMode();
|
|
3185
|
-
const unifiedDir =
|
|
3186
|
-
const legacyDir =
|
|
3187
|
-
const agentDir =
|
|
3188
|
-
const hasLocalConfig =
|
|
3323
|
+
const unifiedDir = join13(opts.configDir, codeName, "provision");
|
|
3324
|
+
const legacyDir = join13(opts.configDir, codeName, "claudecode", "provision");
|
|
3325
|
+
const agentDir = existsSync7(unifiedDir) ? unifiedDir : legacyDir;
|
|
3326
|
+
const hasLocalConfig = existsSync7(agentDir);
|
|
3189
3327
|
let apiChannels = null;
|
|
3190
3328
|
let apiAgent = null;
|
|
3191
3329
|
if (getApiKey()) {
|
|
@@ -3218,34 +3356,34 @@ async function agentShowCommand(codeName, opts) {
|
|
|
3218
3356
|
let openclawConfig = null;
|
|
3219
3357
|
let agentState = null;
|
|
3220
3358
|
if (hasLocalConfig) {
|
|
3221
|
-
const charterPath =
|
|
3222
|
-
if (
|
|
3223
|
-
const raw =
|
|
3359
|
+
const charterPath = join13(agentDir, "CHARTER.md");
|
|
3360
|
+
if (existsSync7(charterPath)) {
|
|
3361
|
+
const raw = readFileSync7(charterPath, "utf-8");
|
|
3224
3362
|
const parsed = extractFrontmatter(raw);
|
|
3225
3363
|
if (parsed.frontmatter) {
|
|
3226
3364
|
charter = parsed.frontmatter;
|
|
3227
3365
|
}
|
|
3228
3366
|
}
|
|
3229
|
-
const toolsPath =
|
|
3230
|
-
if (
|
|
3231
|
-
const raw =
|
|
3367
|
+
const toolsPath = join13(agentDir, "TOOLS.md");
|
|
3368
|
+
if (existsSync7(toolsPath)) {
|
|
3369
|
+
const raw = readFileSync7(toolsPath, "utf-8");
|
|
3232
3370
|
const parsed = extractFrontmatter(raw);
|
|
3233
3371
|
if (parsed.frontmatter) {
|
|
3234
3372
|
tools = parsed.frontmatter;
|
|
3235
3373
|
}
|
|
3236
3374
|
}
|
|
3237
|
-
const openclawPath =
|
|
3238
|
-
if (
|
|
3375
|
+
const openclawPath = join13(agentDir, "openclaw.json5");
|
|
3376
|
+
if (existsSync7(openclawPath)) {
|
|
3239
3377
|
try {
|
|
3240
|
-
const raw =
|
|
3378
|
+
const raw = readFileSync7(openclawPath, "utf-8");
|
|
3241
3379
|
openclawConfig = JSON52.parse(raw);
|
|
3242
3380
|
} catch {
|
|
3243
3381
|
}
|
|
3244
3382
|
}
|
|
3245
|
-
const statePath =
|
|
3246
|
-
if (
|
|
3383
|
+
const statePath = join13(opts.configDir, "manager-state.json");
|
|
3384
|
+
if (existsSync7(statePath)) {
|
|
3247
3385
|
try {
|
|
3248
|
-
const raw =
|
|
3386
|
+
const raw = readFileSync7(statePath, "utf-8");
|
|
3249
3387
|
const state = JSON.parse(raw);
|
|
3250
3388
|
agentState = state.agents?.find((a) => a.codeName === codeName) ?? null;
|
|
3251
3389
|
} catch {
|
|
@@ -3582,24 +3720,24 @@ async function kanbanRecurringDisableCommand(titleOrId, opts) {
|
|
|
3582
3720
|
}
|
|
3583
3721
|
|
|
3584
3722
|
// src/commands/setup.ts
|
|
3585
|
-
import { existsSync as
|
|
3586
|
-
import { join as
|
|
3587
|
-
import { homedir as
|
|
3723
|
+
import { existsSync as existsSync8, readFileSync as readFileSync8, writeFileSync as writeFileSync8, mkdirSync as mkdirSync7, accessSync, constants as fsConstants } from "fs";
|
|
3724
|
+
import { join as join14, dirname as dirname3 } from "path";
|
|
3725
|
+
import { homedir as homedir5 } from "os";
|
|
3588
3726
|
import chalk16 from "chalk";
|
|
3589
3727
|
import ora14 from "ora";
|
|
3590
3728
|
function detectShellProfile() {
|
|
3591
3729
|
const shell = process.env["SHELL"] ?? "";
|
|
3592
|
-
const home =
|
|
3730
|
+
const home = homedir5();
|
|
3593
3731
|
if (shell.includes("zsh")) {
|
|
3594
|
-
return
|
|
3732
|
+
return join14(home, ".zshrc");
|
|
3595
3733
|
}
|
|
3596
3734
|
if (shell.includes("fish")) {
|
|
3597
|
-
const fishConfig =
|
|
3735
|
+
const fishConfig = join14(home, ".config", "fish", "config.fish");
|
|
3598
3736
|
return fishConfig;
|
|
3599
3737
|
}
|
|
3600
|
-
const bashrc =
|
|
3601
|
-
if (
|
|
3602
|
-
return
|
|
3738
|
+
const bashrc = join14(home, ".bashrc");
|
|
3739
|
+
if (existsSync8(bashrc)) return bashrc;
|
|
3740
|
+
return join14(home, ".bash_profile");
|
|
3603
3741
|
}
|
|
3604
3742
|
function maybeWriteSystemWideEnv(apiUrl, apiKey, consoleUrl) {
|
|
3605
3743
|
const empty = { etcEnvironment: false, profileD: false, bashrc: false };
|
|
@@ -3625,14 +3763,14 @@ function quoteForFishShell(value) {
|
|
|
3625
3763
|
}
|
|
3626
3764
|
function writeEtcEnvironment(apiUrl, apiKey, consoleUrl) {
|
|
3627
3765
|
const envPath = "/etc/environment";
|
|
3628
|
-
if (!
|
|
3766
|
+
if (!existsSync8(envPath)) return false;
|
|
3629
3767
|
try {
|
|
3630
3768
|
accessSync(envPath, fsConstants.W_OK);
|
|
3631
3769
|
} catch {
|
|
3632
3770
|
return false;
|
|
3633
3771
|
}
|
|
3634
3772
|
try {
|
|
3635
|
-
const current =
|
|
3773
|
+
const current = readFileSync8(envPath, "utf-8");
|
|
3636
3774
|
const stripped = current.split(/\r?\n/).filter((line) => !/^\s*(?:export\s+)?AGT_(?:HOST|API_KEY|CONSOLE_URL)=/.test(line)).join("\n");
|
|
3637
3775
|
const base = stripped.endsWith("\n") || stripped.length === 0 ? stripped : `${stripped}
|
|
3638
3776
|
`;
|
|
@@ -3643,7 +3781,7 @@ function writeEtcEnvironment(apiUrl, apiKey, consoleUrl) {
|
|
|
3643
3781
|
if (consoleUrl) lines.push(`AGT_CONSOLE_URL=${quoteForEtcEnvironment(consoleUrl)}`);
|
|
3644
3782
|
const appended = `${base}${lines.join("\n")}
|
|
3645
3783
|
`;
|
|
3646
|
-
|
|
3784
|
+
writeFileSync8(envPath, appended, { mode: 420 });
|
|
3647
3785
|
return true;
|
|
3648
3786
|
} catch {
|
|
3649
3787
|
return false;
|
|
@@ -3651,7 +3789,7 @@ function writeEtcEnvironment(apiUrl, apiKey, consoleUrl) {
|
|
|
3651
3789
|
}
|
|
3652
3790
|
function writeProfileDScript(apiUrl, apiKey, consoleUrl) {
|
|
3653
3791
|
const profileD = "/etc/profile.d";
|
|
3654
|
-
if (!
|
|
3792
|
+
if (!existsSync8(profileD)) return false;
|
|
3655
3793
|
try {
|
|
3656
3794
|
accessSync(profileD, fsConstants.W_OK);
|
|
3657
3795
|
} catch {
|
|
@@ -3666,7 +3804,7 @@ function writeProfileDScript(apiUrl, apiKey, consoleUrl) {
|
|
|
3666
3804
|
];
|
|
3667
3805
|
if (consoleUrl) lines.push(`export AGT_CONSOLE_URL=${quoteForPosixShell(consoleUrl)}`);
|
|
3668
3806
|
lines.push("");
|
|
3669
|
-
|
|
3807
|
+
writeFileSync8(scriptPath, lines.join("\n"), { mode: 420 });
|
|
3670
3808
|
return true;
|
|
3671
3809
|
} catch {
|
|
3672
3810
|
return false;
|
|
@@ -3674,14 +3812,14 @@ function writeProfileDScript(apiUrl, apiKey, consoleUrl) {
|
|
|
3674
3812
|
}
|
|
3675
3813
|
function ensureBashrcSourcesProfileD() {
|
|
3676
3814
|
const bashrc = "/etc/bashrc";
|
|
3677
|
-
if (!
|
|
3815
|
+
if (!existsSync8(bashrc)) return false;
|
|
3678
3816
|
try {
|
|
3679
3817
|
accessSync(bashrc, fsConstants.W_OK);
|
|
3680
3818
|
} catch {
|
|
3681
3819
|
return false;
|
|
3682
3820
|
}
|
|
3683
3821
|
try {
|
|
3684
|
-
const current =
|
|
3822
|
+
const current = readFileSync8(bashrc, "utf-8");
|
|
3685
3823
|
const marker = "# Augmented (agt) \u2014 source system-wide AGT env";
|
|
3686
3824
|
if (current.includes(marker)) return true;
|
|
3687
3825
|
const snippet = [
|
|
@@ -3692,7 +3830,7 @@ function ensureBashrcSourcesProfileD() {
|
|
|
3692
3830
|
"fi",
|
|
3693
3831
|
""
|
|
3694
3832
|
].join("\n");
|
|
3695
|
-
|
|
3833
|
+
writeFileSync8(bashrc, current + snippet);
|
|
3696
3834
|
return true;
|
|
3697
3835
|
} catch {
|
|
3698
3836
|
return false;
|
|
@@ -3807,12 +3945,12 @@ async function setupCommand(token) {
|
|
|
3807
3945
|
);
|
|
3808
3946
|
}
|
|
3809
3947
|
const exportLines = buildExportLines(shell, finalApiUrl, setupResult.api_key, consoleUrl);
|
|
3810
|
-
const profileDir =
|
|
3811
|
-
if (!
|
|
3812
|
-
|
|
3948
|
+
const profileDir = dirname3(profilePath);
|
|
3949
|
+
if (!existsSync8(profileDir)) {
|
|
3950
|
+
mkdirSync7(profileDir, { recursive: true });
|
|
3813
3951
|
}
|
|
3814
3952
|
const marker = "# Augmented (agt) host configuration";
|
|
3815
|
-
const current =
|
|
3953
|
+
const current = existsSync8(profilePath) ? readFileSync8(profilePath, "utf-8") : "";
|
|
3816
3954
|
let updated;
|
|
3817
3955
|
if (current.includes(marker)) {
|
|
3818
3956
|
updated = current.replace(
|
|
@@ -3825,7 +3963,7 @@ async function setupCommand(token) {
|
|
|
3825
3963
|
} else {
|
|
3826
3964
|
updated = current + exportLines;
|
|
3827
3965
|
}
|
|
3828
|
-
|
|
3966
|
+
writeFileSync8(profilePath, updated.endsWith("\n") ? updated : `${updated}
|
|
3829
3967
|
`);
|
|
3830
3968
|
if (!json) {
|
|
3831
3969
|
success(`Environment variables written to ${chalk16.bold(profilePath)}`);
|
|
@@ -3843,7 +3981,7 @@ async function setupCommand(token) {
|
|
|
3843
3981
|
const managerSpinner = ora14({ text: "Starting manager daemon\u2026", isSilent: json });
|
|
3844
3982
|
managerSpinner.start();
|
|
3845
3983
|
try {
|
|
3846
|
-
const configDir =
|
|
3984
|
+
const configDir = join14(homedir5(), ".augmented");
|
|
3847
3985
|
const { pid } = startWatchdog({ intervalMs: 1e4, configDir, detached: true });
|
|
3848
3986
|
managerSpinner.succeed(`Manager started (PID ${pid})`);
|
|
3849
3987
|
} catch (err) {
|
|
@@ -4391,10 +4529,10 @@ async function acpxCloseCommand(agent2, _opts, cmd) {
|
|
|
4391
4529
|
|
|
4392
4530
|
// src/commands/update.ts
|
|
4393
4531
|
import { execFileSync, execSync } from "child_process";
|
|
4394
|
-
import { existsSync as
|
|
4532
|
+
import { existsSync as existsSync9, realpathSync as realpathSync2 } from "fs";
|
|
4395
4533
|
import chalk18 from "chalk";
|
|
4396
4534
|
import ora16 from "ora";
|
|
4397
|
-
var cliVersion = true ? "0.27.
|
|
4535
|
+
var cliVersion = true ? "0.27.8" : "dev";
|
|
4398
4536
|
async function fetchLatestVersion() {
|
|
4399
4537
|
const host2 = getHost();
|
|
4400
4538
|
if (!host2) return null;
|
|
@@ -4498,7 +4636,7 @@ function performUpdate(version) {
|
|
|
4498
4636
|
function detectBrewOwner() {
|
|
4499
4637
|
for (const prefix of ["/home/linuxbrew/.linuxbrew", "/opt/homebrew", "/usr/local"]) {
|
|
4500
4638
|
const cellar = `${prefix}/Cellar`;
|
|
4501
|
-
if (!
|
|
4639
|
+
if (!existsSync9(cellar)) continue;
|
|
4502
4640
|
try {
|
|
4503
4641
|
return execSync(`stat -c %U "${cellar}" 2>/dev/null || stat -f %Su "${cellar}"`, { encoding: "utf-8" }).trim() || null;
|
|
4504
4642
|
} catch {
|
|
@@ -4926,7 +5064,7 @@ function handleError(err) {
|
|
|
4926
5064
|
}
|
|
4927
5065
|
|
|
4928
5066
|
// src/bin/agt.ts
|
|
4929
|
-
var cliVersion2 = true ? "0.27.
|
|
5067
|
+
var cliVersion2 = true ? "0.27.8" : "dev";
|
|
4930
5068
|
var program = new Command();
|
|
4931
5069
|
program.name("agt").description("Augmented CLI \u2014 agent provisioning and management").version(cliVersion2).option("--json", "Emit machine-readable JSON output (suppress spinners and colors)").option("--skip-update-check", "Skip the automatic update check on startup");
|
|
4932
5070
|
program.hook("preAction", (thisCommand) => {
|
|
@@ -5002,16 +5140,16 @@ host.command("pair <host-name>").description("Start an SSM port-forward + shell
|
|
|
5002
5140
|
})
|
|
5003
5141
|
);
|
|
5004
5142
|
var manager = program.command("manager").description("Host config sync daemon \u2014 keeps local agent files in sync with API");
|
|
5005
|
-
manager.command("start").description("Start the manager daemon (polls API for config changes and detects local drift)").option("--interval <seconds>", "Poll interval in seconds (min 5)", "10").option("--config-dir <dir>", "Config directory for agent files",
|
|
5006
|
-
manager.command("stop").description("Stop the running manager daemon").option("--config-dir <dir>", "Config directory for agent files",
|
|
5007
|
-
manager.command("status").description("Show the current manager daemon status and discovered agents").option("--config-dir <dir>", "Config directory for agent files",
|
|
5008
|
-
manager.command("watch").description("Live TUI dashboard \u2014 per-agent boxes, drill-in, log tail. Read-only (ENG-4555).").option("--config-dir <dir>", "Config directory for agent files",
|
|
5009
|
-
manager.command("install").description("Install OS-level supervisor (launchd LaunchAgent on macOS) so the manager auto-restarts after crash, reboot, or self-update (ENG-4593)").option("--interval <seconds>", "Poll interval in seconds (min 5)", "10").option("--config-dir <dir>", "Config directory for agent files",
|
|
5143
|
+
manager.command("start").description("Start the manager daemon (polls API for config changes and detects local drift)").option("--interval <seconds>", "Poll interval in seconds (min 5)", "10").option("--config-dir <dir>", "Config directory for agent files", join15(homedir6(), ".augmented")).option("--supervise", "Wrap the manager in a respawn-on-clean-exit loop so auto-upgrades can restart it transparently (ENG-4488)", false).action(managerStartCommand);
|
|
5144
|
+
manager.command("stop").description("Stop the running manager daemon").option("--config-dir <dir>", "Config directory for agent files", join15(homedir6(), ".augmented")).action(managerStopCommand);
|
|
5145
|
+
manager.command("status").description("Show the current manager daemon status and discovered agents").option("--config-dir <dir>", "Config directory for agent files", join15(homedir6(), ".augmented")).action(managerStatusCommand);
|
|
5146
|
+
manager.command("watch").description("Live TUI dashboard \u2014 per-agent boxes, drill-in, log tail. Read-only (ENG-4555).").option("--config-dir <dir>", "Config directory for agent files", join15(homedir6(), ".augmented")).option("--no-tui", "Skip the TUI and stream the manager log to stdout instead (CI / scripts)").action(managerWatchCommand);
|
|
5147
|
+
manager.command("install").description("Install OS-level supervisor (launchd LaunchAgent on macOS) so the manager auto-restarts after crash, reboot, or self-update (ENG-4593)").option("--interval <seconds>", "Poll interval in seconds (min 5)", "10").option("--config-dir <dir>", "Config directory for agent files", join15(homedir6(), ".augmented")).action(managerInstallCommand);
|
|
5010
5148
|
manager.command("uninstall").description("Remove the OS-level supervisor (launchctl unload + delete plist on macOS). Idempotent.").action(managerUninstallCommand);
|
|
5011
5149
|
manager.command("install-system-unit").description("Install a system-level systemd unit (Linux, root) so the manager auto-starts on every boot. For headless EC2 hosts \u2014 survives reboot without `loginctl enable-linger`. (ENG-4706)").option("--interval <seconds>", "Poll interval in seconds (min 5)", "10").option("--config-dir <dir>", "Config directory for agent files (defaults to /root/.augmented or /home/<user>/.augmented)").option("--user <name>", "Unix user the manager runs as", "root").action(managerInstallSystemUnitCommand);
|
|
5012
5150
|
manager.command("uninstall-system-unit").description("Remove the system-level systemd unit (Linux, root). Idempotent. (ENG-4706)").action(managerUninstallSystemUnitCommand);
|
|
5013
5151
|
var agent = program.command("agent").description("Inspect and manage agents");
|
|
5014
|
-
agent.command("show <code-name>").description("Display an agent's provisioned OpenClaw configuration").option("--config-dir <dir>", "Config directory",
|
|
5152
|
+
agent.command("show <code-name>").description("Display an agent's provisioned OpenClaw configuration").option("--config-dir <dir>", "Config directory", join15(homedir6(), ".augmented")).option("--all-channels", "Show all channels (including disabled)").action(agentShowCommand);
|
|
5015
5153
|
var kanban = program.command("kanban").description("Manage agent kanban boards");
|
|
5016
5154
|
kanban.command("list").description("List kanban board items for an agent").requiredOption("--agent <code-name>", "Agent code name").action(kanbanListCommand);
|
|
5017
5155
|
kanban.command("add <title>").description("Add a new item to an agent kanban board").requiredOption("--agent <code-name>", "Agent code name").option("--priority <1|2|3>", "Priority: 1=high, 2=medium, 3=low", "2").option("--status <status>", "Initial status: backlog | todo | in_progress", "todo").option("--description <text>", "Item description").option("--estimate <minutes>", "Estimated time in minutes").option("--deliverable <text>", "Expected output/deliverable").action(kanbanAddCommand);
|