@songsid/agend 2.2.0-beta.15 → 2.2.0-beta.17
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 +1 -0
- package/README.zh-TW.md +1 -0
- package/dist/backend/antigravity.d.ts +25 -0
- package/dist/backend/antigravity.js +94 -9
- package/dist/backend/antigravity.js.map +1 -1
- package/dist/cli.js +19 -0
- package/dist/cli.js.map +1 -1
- package/dist/compact-watch.d.ts +78 -0
- package/dist/compact-watch.js +247 -0
- package/dist/compact-watch.js.map +1 -0
- package/dist/daemon.js +46 -6
- package/dist/daemon.js.map +1 -1
- package/dist/fleet-manager.d.ts +3 -0
- package/dist/fleet-manager.js +76 -5
- package/dist/fleet-manager.js.map +1 -1
- package/dist/locale.js +4 -0
- package/dist/locale.js.map +1 -1
- package/dist/service-installer.d.ts +24 -0
- package/dist/service-installer.js +49 -1
- package/dist/service-installer.js.map +1 -1
- package/dist/topic-commands.d.ts +23 -2
- package/dist/topic-commands.js +48 -19
- package/dist/topic-commands.js.map +1 -1
- package/dist/transcript-jsonl.d.ts +7 -2
- package/dist/transcript-jsonl.js +13 -7
- package/dist/transcript-jsonl.js.map +1 -1
- package/dist/ui/chat-store.js +32 -2
- package/dist/ui/chat-strings.js +8 -2
- package/dist/ui/chat-thread.js +75 -12
- package/dist/ui/panel-chat.js +4 -1
- package/dist/ui/shared/app.css +1 -0
- package/dist/usage/providers.d.ts +28 -8
- package/dist/usage/providers.js +96 -41
- package/dist/usage/providers.js.map +1 -1
- package/dist/web-api.js +1 -1
- package/dist/web-api.js.map +1 -1
- package/dist/web-commands.d.ts +14 -1
- package/dist/web-commands.js +6 -3
- package/dist/web-commands.js.map +1 -1
- package/dist/web-upload.d.ts +7 -3
- package/dist/web-upload.js +20 -8
- package/dist/web-upload.js.map +1 -1
- package/package.json +1 -1
package/dist/fleet-manager.d.ts
CHANGED
|
@@ -855,6 +855,9 @@ export declare class FleetManager implements FleetContext, LifecycleContext, Arc
|
|
|
855
855
|
/** #1218: the Log tab's on-demand service — made on first use; with `web.log_tab` off it answers off and does nothing. */
|
|
856
856
|
private logService;
|
|
857
857
|
private get log();
|
|
858
|
+
/** Board 003648ac: a web /compact followed to its end, from the transcript the Log reads (none: nothing to follow). */
|
|
859
|
+
private compactWatchService;
|
|
860
|
+
private get compactWatch();
|
|
858
861
|
/** #1218: GET /ui/steps — an instance's steps, read on demand (null: no such instance). */
|
|
859
862
|
logSteps(name: string, q: LogQuery): Promise<LogAnswer | null>;
|
|
860
863
|
/**
|
package/dist/fleet-manager.js
CHANGED
|
@@ -194,6 +194,8 @@ import { GENERAL_PAUSE_ERROR, isGeneralInstance } from "./general-instance.js";
|
|
|
194
194
|
import { buildOrgChart } from "./web-org.js";
|
|
195
195
|
import { CacheService, WINDOWS } from "./cache-service.js";
|
|
196
196
|
import { runWebCommand } from "./web-commands.js";
|
|
197
|
+
import { CompactWatch, launchIdentity } from "./compact-watch.js";
|
|
198
|
+
import { agyLegacyAgentsFile, danglingSymlink, migrateAgyAgentsFile } from "./backend/antigravity.js";
|
|
197
199
|
import { claudeConfigDirFor, claudeProjectKey } from "./backend/claude-code.js";
|
|
198
200
|
import { sharedRolloutIndex } from "./rollout-index.js";
|
|
199
201
|
import { mayUseTool, resolveToolSet, scheduleOpRefusal, toolForIpcType, toolRefusedMessage, } from "./tool-permissions.js";
|
|
@@ -2811,6 +2813,24 @@ export class FleetManager {
|
|
|
2811
2813
|
emit: (event, data) => this.emitSseEvent(event, data),
|
|
2812
2814
|
});
|
|
2813
2815
|
}
|
|
2816
|
+
/** Board 003648ac: a web /compact followed to its end, from the transcript the Log reads (none: nothing to follow). */
|
|
2817
|
+
compactWatchService = null;
|
|
2818
|
+
get compactWatch() {
|
|
2819
|
+
return this.compactWatchService ??= new CompactWatch({
|
|
2820
|
+
source: (name) => { const src = this.logSource(name); return { path: src.path, format: src.format }; },
|
|
2821
|
+
// The launch that runs it now (the same value the daemon sends with raw_paste_written).
|
|
2822
|
+
owner: (name) => {
|
|
2823
|
+
const daemon = this.lifecycle.daemons.get(name);
|
|
2824
|
+
try {
|
|
2825
|
+
return daemon ? launchIdentity(daemon.getInteractionSnapshot().owner) : null;
|
|
2826
|
+
}
|
|
2827
|
+
catch {
|
|
2828
|
+
return null;
|
|
2829
|
+
}
|
|
2830
|
+
},
|
|
2831
|
+
changed: () => this.emitSseEvent("status", this.getUiStatus()),
|
|
2832
|
+
});
|
|
2833
|
+
}
|
|
2814
2834
|
/** #1218: GET /ui/steps — an instance's steps, read on demand (null: no such instance). */
|
|
2815
2835
|
logSteps(name, q) { return this.log.steps(name, q); }
|
|
2816
2836
|
/**
|
|
@@ -7257,6 +7277,11 @@ export class FleetManager {
|
|
|
7257
7277
|
});
|
|
7258
7278
|
}
|
|
7259
7279
|
}
|
|
7280
|
+
else if (msg.type === "raw_paste_written") {
|
|
7281
|
+
// Board 003648ac: a web /compact's paste reached the pane (or never will): its watch starts, or ends as lost.
|
|
7282
|
+
if (typeof msg.id === "string")
|
|
7283
|
+
this.compactWatchService?.pasted(name, msg.id, msg.outcome === "written", { owner: msg.owner, checkpoint: msg.checkpoint });
|
|
7284
|
+
}
|
|
7260
7285
|
else if (msg.type === "runtime_switch_result") {
|
|
7261
7286
|
// #1690: what our own runtime /model came to (the daemon answered claude's "Switch model?" or saw the result).
|
|
7262
7287
|
const waiter = typeof msg.id === "string" ? this.runtimeSwitchWaiters.get(msg.id) : undefined;
|
|
@@ -10259,6 +10284,7 @@ export class FleetManager {
|
|
|
10259
10284
|
// must not be shown the old one's conversation, and deleted names must not pile up.
|
|
10260
10285
|
this.webChatHistory.forget(name);
|
|
10261
10286
|
this.webFiles.forget(name);
|
|
10287
|
+
this.compactWatchService?.forget(name);
|
|
10262
10288
|
// #1664: and it is nobody's favorite any more (every device sees that at its next status frame).
|
|
10263
10289
|
try {
|
|
10264
10290
|
this.webPrefs.forgetInstance(name);
|
|
@@ -12666,7 +12692,22 @@ export class FleetManager {
|
|
|
12666
12692
|
return this.classicChannels?.getChannelIdByInstance(instance) !== undefined ? "classic" : null;
|
|
12667
12693
|
},
|
|
12668
12694
|
ctx: (instance) => this.topicCommands.getCtxText(instance),
|
|
12669
|
-
|
|
12695
|
+
// Board 003648ac: a watch for the paste, armed when the daemon says it was written (raw_paste_written); one
|
|
12696
|
+
// for a command that was not handed over is dropped.
|
|
12697
|
+
compact: async (instance, instructions) => {
|
|
12698
|
+
let watch = null;
|
|
12699
|
+
try {
|
|
12700
|
+
const r = this.topicCommands.compactInstance(instance, instructions, () => (watch = this.compactWatch.begin(instance)));
|
|
12701
|
+
if (!r.sent && watch)
|
|
12702
|
+
this.compactWatch.cancel(instance, watch);
|
|
12703
|
+
return { ...r, watch: r.sent ? watch : null };
|
|
12704
|
+
}
|
|
12705
|
+
catch (err) {
|
|
12706
|
+
if (watch)
|
|
12707
|
+
this.compactWatch.cancel(instance, watch);
|
|
12708
|
+
throw err;
|
|
12709
|
+
}
|
|
12710
|
+
},
|
|
12670
12711
|
applyModel: (instance, name) => this.applyModel(instance, name),
|
|
12671
12712
|
modelChoices: choicesFromCache,
|
|
12672
12713
|
applyEffort: (instance, level) => this.applyEffort(instance, level),
|
|
@@ -12740,7 +12781,8 @@ export class FleetManager {
|
|
|
12740
12781
|
// sendClear sends its first IPC synchronously: no await separates this check from the effect.
|
|
12741
12782
|
if (this.shuttingDown || !entry.fence())
|
|
12742
12783
|
return { status: 409, text: t("menu.click_stale") };
|
|
12743
|
-
|
|
12784
|
+
const r = this.topicCommands.clearInstance(instance);
|
|
12785
|
+
return r.sent ? { status: 200, text: r.text, sent: true } : { status: 409, text: r.text };
|
|
12744
12786
|
},
|
|
12745
12787
|
t: (key, ...args) => t(key, ...args),
|
|
12746
12788
|
}, input, opts);
|
|
@@ -14676,12 +14718,12 @@ export class FleetManager {
|
|
|
14676
14718
|
"codex": "AGENTS.md",
|
|
14677
14719
|
"opencode": "AGENTS.md",
|
|
14678
14720
|
"kiro-cli": ".kiro/steering/project.md",
|
|
14679
|
-
// Grok reads AGENTS.md project docs; agy reads .agents/
|
|
14721
|
+
// Grok reads AGENTS.md project docs; agy reads .agents/AGENTS.md (board 0340ec89: not the lowercase name) — the
|
|
14680
14722
|
// same files their writeConfig() appends fleet instructions to.
|
|
14681
14723
|
"grok": "AGENTS.md",
|
|
14682
14724
|
// muse init scaffolds AGENTS.md and the binary reads it as project rules.
|
|
14683
14725
|
"muse": "AGENTS.md",
|
|
14684
|
-
"antigravity": ".agents/
|
|
14726
|
+
"antigravity": ".agents/AGENTS.md",
|
|
14685
14727
|
"mock": "CLAUDE.md",
|
|
14686
14728
|
};
|
|
14687
14729
|
static GENERAL_INSTRUCTIONS = `# Fleet Coordinator
|
|
@@ -14721,10 +14763,17 @@ Plus the operational skills (fleet-health, instance-lifecycle, scheduling, sessi
|
|
|
14721
14763
|
ensureGeneralInstructionsSync(workDir, backendName, instanceName) {
|
|
14722
14764
|
const backend = backendName ?? "claude-code";
|
|
14723
14765
|
workDir = this.resolveKnowledgeWorkDir(workDir, backend, instanceName);
|
|
14766
|
+
// Board 0340ec89: General's file from before, under the lowercase name agy never read, becomes the one it reads.
|
|
14767
|
+
if (backend === "antigravity")
|
|
14768
|
+
migrateAgyAgentsFile(workDir);
|
|
14724
14769
|
const filename = FleetManager.INSTRUCTIONS_FILENAME[backend] ?? "CLAUDE.md";
|
|
14725
14770
|
const filePath = join(workDir, filename);
|
|
14726
14771
|
mkdirSync(dirname(filePath), { recursive: true });
|
|
14727
|
-
if (
|
|
14772
|
+
if (backend === "antigravity" && danglingSymlink(filePath)) {
|
|
14773
|
+
// #1914 review: a person's dangling symlink there is kept and not followed (nothing created where it points).
|
|
14774
|
+
this.logger.warn({ filePath }, "General's agy instructions file is a dangling symlink; left as it is, not written");
|
|
14775
|
+
}
|
|
14776
|
+
else if (!existsSync(filePath)) {
|
|
14728
14777
|
writeFileSync(filePath, FleetManager.GENERAL_INSTRUCTIONS, "utf-8");
|
|
14729
14778
|
this.logger.info({ filePath }, "Created general instance instructions file");
|
|
14730
14779
|
}
|
|
@@ -14821,6 +14870,8 @@ Plus the operational skills (fleet-health, instance-lifecycle, scheduling, sessi
|
|
|
14821
14870
|
}
|
|
14822
14871
|
const filename = FleetManager.INSTRUCTIONS_FILENAME[backend] ?? "CLAUDE.md";
|
|
14823
14872
|
const instructionsPath = join(workDir, filename);
|
|
14873
|
+
if (backend === "antigravity" && danglingSymlink(instructionsPath))
|
|
14874
|
+
return; // kept, not followed (#1914 review; logged above)
|
|
14824
14875
|
const body = files.map(f => readFileSync(join(srcSteering, f), "utf-8").trim()).join("\n\n");
|
|
14825
14876
|
const block = `${FleetManager.STEERING_BLOCK_BEGIN}\n${body}\n${FleetManager.STEERING_BLOCK_END}`;
|
|
14826
14877
|
let existing = "";
|
|
@@ -14841,6 +14892,22 @@ Plus the operational skills (fleet-health, instance-lifecycle, scheduling, sessi
|
|
|
14841
14892
|
mkdirSync(dirname(instructionsPath), { recursive: true });
|
|
14842
14893
|
writeFileSync(instructionsPath, next);
|
|
14843
14894
|
}
|
|
14895
|
+
// Board 0340ec89: a legacy agy file that stays beside the new one (a person's own) loses only AgEnD's block.
|
|
14896
|
+
const legacy = backend === "antigravity" ? agyLegacyAgentsFile(workDir) : null;
|
|
14897
|
+
if (legacy) {
|
|
14898
|
+
try {
|
|
14899
|
+
const old = readFileSync(legacy, "utf-8");
|
|
14900
|
+
const b = old.indexOf(FleetManager.STEERING_BLOCK_BEGIN), e = old.indexOf(FleetManager.STEERING_BLOCK_END);
|
|
14901
|
+
if (b !== -1 && e > b) {
|
|
14902
|
+
const rest = (old.slice(0, b).trimEnd() + "\n" + old.slice(e + FleetManager.STEERING_BLOCK_END.length).trimStart()).trim();
|
|
14903
|
+
if (rest)
|
|
14904
|
+
writeFileSync(legacy, rest + "\n");
|
|
14905
|
+
else
|
|
14906
|
+
rmSync(legacy, { force: true });
|
|
14907
|
+
}
|
|
14908
|
+
}
|
|
14909
|
+
catch { /* best effort: the new file already has the block */ }
|
|
14910
|
+
}
|
|
14844
14911
|
}
|
|
14845
14912
|
static STEERING_BLOCK_BEGIN = "<!-- >>> agend:core-rules — managed by AgEnD; edits inside this block are overwritten -->";
|
|
14846
14913
|
static STEERING_BLOCK_END = "<!-- <<< agend:core-rules -->";
|
|
@@ -17320,6 +17387,7 @@ Plus the operational skills (fleet-health, instance-lifecycle, scheduling, sessi
|
|
|
17320
17387
|
this.eventLogPruneTimer = null;
|
|
17321
17388
|
}
|
|
17322
17389
|
this.logService?.unwatchAll(); // #1218: a Log's watch timers end with the fleet
|
|
17390
|
+
this.compactWatchService?.stopAll();
|
|
17323
17391
|
if (this.outboxPruneTimer) {
|
|
17324
17392
|
clearInterval(this.outboxPruneTimer);
|
|
17325
17393
|
this.outboxPruneTimer = null;
|
|
@@ -19972,6 +20040,7 @@ Plus the operational skills (fleet-health, instance-lifecycle, scheduling, sessi
|
|
|
19972
20040
|
const effort = (effortStrategy === "unsupported" || isAgy) ? null : effortResolved.effort;
|
|
19973
20041
|
const effort_source = (effortStrategy === "unsupported" || isAgy) ? null : effortResolved.source;
|
|
19974
20042
|
const identity = resolveInstanceIdentity({ cfg: this.fleetConfig?.instances[name], classic: classicRooms.get(name), profile: profiles.get(name) });
|
|
20043
|
+
const compact = this.compactWatchService?.view(name) ?? null;
|
|
19975
20044
|
let image;
|
|
19976
20045
|
try {
|
|
19977
20046
|
image = this.webIdentityImage(name, identity.display_name, profiles.get(name)?.avatar_path, bots);
|
|
@@ -19999,6 +20068,8 @@ Plus the operational skills (fleet-health, instance-lifecycle, scheduling, sessi
|
|
|
19999
20068
|
effort,
|
|
20000
20069
|
effort_source,
|
|
20001
20070
|
...this.instancePresentation(name),
|
|
20071
|
+
// Board 003648ac: the last web /compact, while it runs and briefly after (the chat's card follows it).
|
|
20072
|
+
...(compact ? { compact } : {}),
|
|
20002
20073
|
};
|
|
20003
20074
|
});
|
|
20004
20075
|
return {
|