@xiaoso/dsh-tool-plus 0.1.8-beta.3 → 0.1.8-beta.4
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/lib/client.js +439 -140
- package/lib/index.mjs +2 -2
- package/lib/{scrapers-DU4u4-Co.mjs → scrapers-BWgeG8qC.mjs} +1 -1
- package/lib/types/web/client/ToolCardShell.d.ts +15 -5
- package/lib/types/web/client/labels.d.ts +1 -1
- package/lib/types/web/client/row-utils.d.ts +28 -8
- package/lib/types/web/client/rows/card-leading.d.ts +37 -0
- package/lib/types/web/client/rows/fallback-card-facts.d.ts +52 -0
- package/lib/{utils-C-Lo_JC6.mjs → utils-CdKv-8uE.mjs} +1 -1
- package/package.json +1 -1
- package/presets/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -3349,6 +3349,7 @@ window.__ModuleLoader__.load({
|
|
|
3349
3349
|
running: "运行中",
|
|
3350
3350
|
done: "完成",
|
|
3351
3351
|
failed: "失败",
|
|
3352
|
+
stopped: "已停止",
|
|
3352
3353
|
cancelled: "已取消",
|
|
3353
3354
|
timedOut: "已超时",
|
|
3354
3355
|
noOutput: "无输出",
|
|
@@ -3412,6 +3413,7 @@ window.__ModuleLoader__.load({
|
|
|
3412
3413
|
running: "Running",
|
|
3413
3414
|
done: "Done",
|
|
3414
3415
|
failed: "Failed",
|
|
3416
|
+
stopped: "Stopped",
|
|
3415
3417
|
cancelled: "Cancelled",
|
|
3416
3418
|
timedOut: "Timed out",
|
|
3417
3419
|
noOutput: "No output",
|
|
@@ -3470,7 +3472,7 @@ window.__ModuleLoader__.load({
|
|
|
3470
3472
|
running: "running",
|
|
3471
3473
|
ok: null,
|
|
3472
3474
|
error: "failed",
|
|
3473
|
-
warning: "
|
|
3475
|
+
warning: "stopped"
|
|
3474
3476
|
};
|
|
3475
3477
|
/** Parsed-argument cache: the node is immutable, so one parse serves every render. */
|
|
3476
3478
|
const parsedArgs = /* @__PURE__ */ new WeakMap();
|
|
@@ -3493,6 +3495,21 @@ window.__ModuleLoader__.load({
|
|
|
3493
3495
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3494
3496
|
}
|
|
3495
3497
|
/**
|
|
3498
|
+
* The call's original argument text.
|
|
3499
|
+
*
|
|
3500
|
+
* A running call carries it directly; a settled result carries the head
|
|
3501
|
+
* backfilled from the in-window `tool/call`, which is absent when window
|
|
3502
|
+
* truncation left that event outside. The text outlives the parse: a call whose
|
|
3503
|
+
* arguments are still streaming is not valid JSON yet, and the shell states its
|
|
3504
|
+
* first line rather than pretending the call said nothing.
|
|
3505
|
+
* @param block - the frozen running-or-settled call node.
|
|
3506
|
+
* @returns the argument text, or `''` when no head survives.
|
|
3507
|
+
*/
|
|
3508
|
+
function cardArgsRaw(block) {
|
|
3509
|
+
const raw = callHead(block)?.argsRaw;
|
|
3510
|
+
return typeof raw === "string" ? raw : "";
|
|
3511
|
+
}
|
|
3512
|
+
/**
|
|
3496
3513
|
* Parse the call's raw argument JSON.
|
|
3497
3514
|
*
|
|
3498
3515
|
* The parsed object is memoized per node (the node is immutable), so repeated
|
|
@@ -3521,30 +3538,26 @@ window.__ModuleLoader__.load({
|
|
|
3521
3538
|
/**
|
|
3522
3539
|
* Run state of one call.
|
|
3523
3540
|
*
|
|
3524
|
-
* A
|
|
3525
|
-
*
|
|
3526
|
-
*
|
|
3527
|
-
*
|
|
3528
|
-
*
|
|
3541
|
+
* A turn stopped mid-call is projected as a settled `isError` block carrying
|
|
3542
|
+
* `error.code === 'interrupted'`; the shipped row model reads that before
|
|
3543
|
+
* `isError`, so a stopped call is amber and named "stopped" rather than failed.
|
|
3544
|
+
* Any other settled `isError` result is an error. A foreground command that
|
|
3545
|
+
* timed out or was cancelled is amber rather than green (the shipped terminal
|
|
3546
|
+
* model reads only the trailing exit marker, which is exactly what the card
|
|
3547
|
+
* owner was told not to trust). A non-zero exit stays `ok`: bash reports a
|
|
3548
|
+
* failing command as result data, and the card's own status pill carries the
|
|
3549
|
+
* red.
|
|
3529
3550
|
* @param block - the frozen running-or-settled call node.
|
|
3530
3551
|
* @returns the card run state.
|
|
3531
3552
|
*/
|
|
3532
3553
|
function cardState(block) {
|
|
3533
3554
|
if (!isSettled(block)) return "running";
|
|
3555
|
+
if (isRecord$2(block.error) && block.error.code === "interrupted") return "warning";
|
|
3534
3556
|
if (block.isError === true) return "error";
|
|
3535
3557
|
const terminal = narrowTerminalCardMeta(cardMeta(block));
|
|
3536
3558
|
if (terminal !== null && terminal.mode === "foreground" && (terminal.timedOut || terminal.aborted)) return "warning";
|
|
3537
3559
|
return "ok";
|
|
3538
3560
|
}
|
|
3539
|
-
/** Map a card run state onto the primitive's dot semantics. */
|
|
3540
|
-
function dotState(state) {
|
|
3541
|
-
switch (state) {
|
|
3542
|
-
case "running": return "ongoing";
|
|
3543
|
-
case "error": return "error";
|
|
3544
|
-
case "warning": return "warning";
|
|
3545
|
-
default: return "done";
|
|
3546
|
-
}
|
|
3547
|
-
}
|
|
3548
3561
|
/**
|
|
3549
3562
|
* The assistive-technology status word for a run state, or `null` when the
|
|
3550
3563
|
* state is already carried by the row's content.
|
|
@@ -3788,15 +3801,339 @@ window.__ModuleLoader__.load({
|
|
|
3788
3801
|
};
|
|
3789
3802
|
}
|
|
3790
3803
|
//#endregion
|
|
3804
|
+
//#region src/web/client/rows/card-leading.ts
|
|
3805
|
+
/**
|
|
3806
|
+
* Wire tool name to glyph family: the shipped name table for the six keys this
|
|
3807
|
+
* plugin shadows, plus its own two tools.
|
|
3808
|
+
*/
|
|
3809
|
+
const GLYPH_BY_TOOL = {
|
|
3810
|
+
bash: "bash",
|
|
3811
|
+
read: "read",
|
|
3812
|
+
write: "edit",
|
|
3813
|
+
edit: "edit",
|
|
3814
|
+
grep: "search",
|
|
3815
|
+
glob: "search",
|
|
3816
|
+
ast_grep: "search",
|
|
3817
|
+
ast_edit: "edit"
|
|
3818
|
+
};
|
|
3819
|
+
/**
|
|
3820
|
+
* Glyph family a row leads with.
|
|
3821
|
+
* @param toolName - the call's wire tool name, when the node carries one.
|
|
3822
|
+
* @returns the family, or `others` (the shipped generic glyph) for an unknown name.
|
|
3823
|
+
*/
|
|
3824
|
+
function leadingGlyph(toolName) {
|
|
3825
|
+
if (typeof toolName !== "string") return "others";
|
|
3826
|
+
return GLYPH_BY_TOOL[toolName] ?? "others";
|
|
3827
|
+
}
|
|
3828
|
+
/**
|
|
3829
|
+
* Whether a run state keeps the row's glyph or replaces it with a state dot.
|
|
3830
|
+
* @param state - the card's run state.
|
|
3831
|
+
* @returns the leading kind; `error` and `warning` are the two dot states.
|
|
3832
|
+
*/
|
|
3833
|
+
function leadingKind(state) {
|
|
3834
|
+
switch (state) {
|
|
3835
|
+
case "error": return "error";
|
|
3836
|
+
case "warning": return "warning";
|
|
3837
|
+
default: return "glyph";
|
|
3838
|
+
}
|
|
3839
|
+
}
|
|
3840
|
+
//#endregion
|
|
3841
|
+
//#region src/web/client/rows/command-card-facts.ts
|
|
3842
|
+
/**
|
|
3843
|
+
* Collapsed-fact builders for the two command-shaped cards: the command a
|
|
3844
|
+
* `bash` description hides, and the rewrite rule an `ast_edit` preview only
|
|
3845
|
+
* shows once expanded.
|
|
3846
|
+
*
|
|
3847
|
+
* Both cards collapse to one head line. `bash`'s head used to be the model's
|
|
3848
|
+
* own `description` — a sentence about intent, never the command that ran — so
|
|
3849
|
+
* the only way to learn what executed was to expand the card. `ast_edit`'s head
|
|
3850
|
+
* names the file and the replacement count, and its body previews the *result*:
|
|
3851
|
+
* the rule that produced that result lives only in the call's `ops` argument,
|
|
3852
|
+
* which no card showed at all. Each builder recovers one fact from the call's
|
|
3853
|
+
* own arguments, so nothing is inferred from output, and a call head that fell
|
|
3854
|
+
* outside the session window degrades to the facts the card already holds.
|
|
3855
|
+
* @module @xiaoso/dsh-tool-plus/web/client/rows/command-card-facts
|
|
3856
|
+
*/
|
|
3857
|
+
/** Whether `value` is a plain object — the only op shape the engine sends. */
|
|
3858
|
+
function isRecord$1(value) {
|
|
3859
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3860
|
+
}
|
|
3861
|
+
/**
|
|
3862
|
+
* The `bash` card's collapsed summary: what ran, placed after the sentence
|
|
3863
|
+
* saying why.
|
|
3864
|
+
*
|
|
3865
|
+
* The command is the fact the head must carry, so the description can never be
|
|
3866
|
+
* the whole summary — it is a prefix at most. Only its first line is used: a
|
|
3867
|
+
* summary is one row high, and the rest of a multi-line command belongs to the
|
|
3868
|
+
* expanded body, which draws the whole thing.
|
|
3869
|
+
* @param description - the model's one-line intent, or `null` when absent.
|
|
3870
|
+
* @param command - the command actually executed (never empty).
|
|
3871
|
+
* @param outcome - the interruption word (`timedOut` / `cancelled`), or `null`.
|
|
3872
|
+
* @returns the outcome alone when the run was interrupted; otherwise the
|
|
3873
|
+
* description joined to the command's first line, or that line alone.
|
|
3874
|
+
*/
|
|
3875
|
+
function bashCardSummary(description, command, outcome) {
|
|
3876
|
+
if (outcome !== null && outcome !== "") return outcome;
|
|
3877
|
+
const intent = description === null ? "" : description.trim();
|
|
3878
|
+
const line = firstLine(command);
|
|
3879
|
+
return intent === "" ? line : `${intent} · ${line}`;
|
|
3880
|
+
}
|
|
3881
|
+
/**
|
|
3882
|
+
* The `ast_edit` card's rule line: the first usable `ops` entry, written the
|
|
3883
|
+
* way the tool's own `ops` argument writes it (`pat → out`).
|
|
3884
|
+
*
|
|
3885
|
+
* Only the first rule is stated, with the count of the entries behind it: the
|
|
3886
|
+
* card exists to preview one change, and a call may carry many rules whose
|
|
3887
|
+
* patterns are whole AST fragments — listing them would bury the preview. The
|
|
3888
|
+
* remaining count is the array tail, not the number of *usable* entries, so it
|
|
3889
|
+
* always describes the call as it was made.
|
|
3890
|
+
* @param args - the call's parsed arguments, or `null` when its head is gone.
|
|
3891
|
+
* @param t - this plugin's card translate seat.
|
|
3892
|
+
* @returns the rule line, or `null` when the call carries no usable rule.
|
|
3893
|
+
*/
|
|
3894
|
+
function astEditRuleLine(args, t) {
|
|
3895
|
+
const ops = args?.ops;
|
|
3896
|
+
if (!Array.isArray(ops)) return null;
|
|
3897
|
+
for (let index = 0; index < ops.length; index += 1) {
|
|
3898
|
+
const op = ops[index];
|
|
3899
|
+
if (!isRecord$1(op)) continue;
|
|
3900
|
+
const pat = argText(op, "pat");
|
|
3901
|
+
if (pat === null) continue;
|
|
3902
|
+
const replacement = op.out;
|
|
3903
|
+
if (typeof replacement !== "string") continue;
|
|
3904
|
+
const rest = ops.length - 1;
|
|
3905
|
+
const rule = `${t("astEdit.rules")}: ${pat} →${replacement === "" ? "" : ` ${replacement}`}`;
|
|
3906
|
+
return rest === 0 ? rule : `${rule} · ${t("astEdit.rulesRest", { count: rest })}`;
|
|
3907
|
+
}
|
|
3908
|
+
return null;
|
|
3909
|
+
}
|
|
3910
|
+
//#endregion
|
|
3911
|
+
//#region src/web/client/rows/read-card-facts.ts
|
|
3912
|
+
/**
|
|
3913
|
+
* Collapsed-summary facts for the `read` card.
|
|
3914
|
+
*
|
|
3915
|
+
* The Host projection strips the inline selector off the path
|
|
3916
|
+
* (`stripReadSelector` in `web/host/read.ts`) because the card's *link* must
|
|
3917
|
+
* point at a real file, and it keeps only the file's own window. The collapsed
|
|
3918
|
+
* head is then the one place where the question the model actually asked is
|
|
3919
|
+
* still readable — and the projected path cannot answer it: a windowed read of
|
|
3920
|
+
* `package.json:22-25,31-34` and a whole-file read of `package.json` project to
|
|
3921
|
+
* the very same string, so the card hides the difference.
|
|
3922
|
+
*
|
|
3923
|
+
* The summary is therefore built from the call's own argument, selector and
|
|
3924
|
+
* all, with the projected path kept as the fallback for a result whose call
|
|
3925
|
+
* head fell outside the session window (a truncated window carries no
|
|
3926
|
+
* `tool/call` event, so no argument survives). That fallback states a fact the
|
|
3927
|
+
* card already holds; nothing is invented.
|
|
3928
|
+
* @module @xiaoso/dsh-tool-plus/web/client/rows/read-card-facts
|
|
3929
|
+
*/
|
|
3930
|
+
/**
|
|
3931
|
+
* The `read` card's collapsed summary: the path the model asked for, keeping
|
|
3932
|
+
* whatever inline selector it carried (`:22-25`, `:raw`, `:conflicts`, `:28-`,
|
|
3933
|
+
* a sqlite row, an archive member) and shortened against the workspace root.
|
|
3934
|
+
*
|
|
3935
|
+
* The selector is deliberately not validated against the read grammar: the head
|
|
3936
|
+
* reports the call verbatim, and a selector this plugin does not recognize is
|
|
3937
|
+
* still what the model typed — substituting the projection's stripped path
|
|
3938
|
+
* would erase the evidence that two calls differ.
|
|
3939
|
+
* @param args - the call's parsed arguments, or `null` when its head is gone.
|
|
3940
|
+
* @param metaPath - the Host-projected path (already selector-free).
|
|
3941
|
+
* @param cwd - the session workspace root, when known.
|
|
3942
|
+
* @returns the workspace-shortened argument path, or the projected path.
|
|
3943
|
+
*/
|
|
3944
|
+
function readCardSummary(args, metaPath, cwd) {
|
|
3945
|
+
return displayPath(argText(args, "path") ?? metaPath, cwd);
|
|
3946
|
+
}
|
|
3947
|
+
//#endregion
|
|
3948
|
+
//#region src/web/client/rows/fallback-card-facts.ts
|
|
3949
|
+
/**
|
|
3950
|
+
* Collapsed-summary facts for the generic card — every row's degradation path.
|
|
3951
|
+
*
|
|
3952
|
+
* A call lands on the generic shell when its own card cannot be built: it is
|
|
3953
|
+
* still running, its result carried no text, its metadata fell outside the
|
|
3954
|
+
* session window, it is a Code Dispatch child, or the Host projected an
|
|
3955
|
+
* interruption the card has no material for. In every one of those cases the
|
|
3956
|
+
* call's ARGUMENTS are the only material left, and the shipped generic row
|
|
3957
|
+
* answers them with the call's own fact: its variant's summary keys first, then
|
|
3958
|
+
* ANY string the payload carries, then the first line of the raw argument text
|
|
3959
|
+
* (`deriveSummary` in ui-tool's `tool-call-model.ts`). It never answers with an
|
|
3960
|
+
* argument count.
|
|
3961
|
+
*
|
|
3962
|
+
* That is the rule here. The count it replaces told the reader nothing: a
|
|
3963
|
+
* directory read, a `:raw` window, a running `grep` and a child call all
|
|
3964
|
+
* collapsed to "1 个参数" — the one thing a degraded row must not do, since the
|
|
3965
|
+
* head is then the only place the fact exists.
|
|
3966
|
+
*
|
|
3967
|
+
* The key preference follows THIS plugin's own tool schemas rather than the
|
|
3968
|
+
* shipped `SUMMARY_KEYS`: our tools replaced the built-in ones with the OMP
|
|
3969
|
+
* native parameter names (`read`/`write` take `path`, `ast_grep` takes `pat`,
|
|
3970
|
+
* `ast_edit` takes `paths`), and the shipped table's `file_path` is what the
|
|
3971
|
+
* built-in tools used. Both spellings are accepted, ours first, so a transcript
|
|
3972
|
+
* recorded before the takeover still states its path.
|
|
3973
|
+
* @module @xiaoso/dsh-tool-plus/web/client/rows/fallback-card-facts
|
|
3974
|
+
*/
|
|
3975
|
+
/**
|
|
3976
|
+
* First entry of a path-list argument (`ast_edit.paths`), tolerating the
|
|
3977
|
+
* single-string form some calls use.
|
|
3978
|
+
* @param args - the call's parsed arguments, or `null`.
|
|
3979
|
+
* @param name - the argument's name.
|
|
3980
|
+
* @returns the first non-empty path, or `null`.
|
|
3981
|
+
*/
|
|
3982
|
+
function firstPath(args, name) {
|
|
3983
|
+
const value = args?.[name];
|
|
3984
|
+
if (typeof value === "string" && value !== "") return value;
|
|
3985
|
+
if (!Array.isArray(value)) return null;
|
|
3986
|
+
for (const entry of value) if (typeof entry === "string" && entry !== "") return entry;
|
|
3987
|
+
return null;
|
|
3988
|
+
}
|
|
3989
|
+
/**
|
|
3990
|
+
* The first non-empty string the payload carries under one of `keys` — the
|
|
3991
|
+
* shipped row's own key-preference rule, first line only (a payload's own
|
|
3992
|
+
* newlines never reach a one-line head).
|
|
3993
|
+
* @param args - the call's parsed arguments, or `null`.
|
|
3994
|
+
* @param keys - argument names, most significant first.
|
|
3995
|
+
* @returns the value, or `null` when none of them is a non-empty string.
|
|
3996
|
+
*/
|
|
3997
|
+
function pickKeys(args, keys) {
|
|
3998
|
+
for (const key of keys) {
|
|
3999
|
+
const value = argText(args, key);
|
|
4000
|
+
if (value !== null) return firstLine(value);
|
|
4001
|
+
}
|
|
4002
|
+
return null;
|
|
4003
|
+
}
|
|
4004
|
+
/**
|
|
4005
|
+
* The `queries` a search call may carry, joined one query per line — the one
|
|
4006
|
+
* special case the shipped row makes before its key table.
|
|
4007
|
+
* @param args - the call's parsed arguments, or `null`.
|
|
4008
|
+
* @returns the joined subject, or `null` when there is no usable query.
|
|
4009
|
+
*/
|
|
4010
|
+
function queriesSubject(args) {
|
|
4011
|
+
const queries = args?.["queries"];
|
|
4012
|
+
if (!Array.isArray(queries)) return null;
|
|
4013
|
+
const parts = queries.filter((query) => typeof query === "string" && query !== "").map(firstLine);
|
|
4014
|
+
return parts.length === 0 ? null : parts.join(", ");
|
|
4015
|
+
}
|
|
4016
|
+
/**
|
|
4017
|
+
* The fact the call states for a key this plugin renders.
|
|
4018
|
+
* @param toolName - the call's wire tool name.
|
|
4019
|
+
* @param args - the call's parsed arguments, or `null`.
|
|
4020
|
+
* @param cwd - the session workspace root, for shortening an absolute path.
|
|
4021
|
+
* @returns the stated fact, or `null` when this key states nothing usable.
|
|
4022
|
+
*/
|
|
4023
|
+
function statedFact(toolName, args, cwd) {
|
|
4024
|
+
switch (toolName) {
|
|
4025
|
+
case "read": {
|
|
4026
|
+
const asked = pickKeys(args, [
|
|
4027
|
+
"path",
|
|
4028
|
+
"file_path",
|
|
4029
|
+
"url"
|
|
4030
|
+
]);
|
|
4031
|
+
return asked === null ? null : readCardSummary(args, asked, cwd);
|
|
4032
|
+
}
|
|
4033
|
+
case "bash": {
|
|
4034
|
+
const command = argText(args, "command");
|
|
4035
|
+
const description = argText(args, "description");
|
|
4036
|
+
if (command === null) return description;
|
|
4037
|
+
return bashCardSummary(description, command, null);
|
|
4038
|
+
}
|
|
4039
|
+
case "write": {
|
|
4040
|
+
const path = pickKeys(args, ["path", "file_path"]);
|
|
4041
|
+
return path === null ? null : displayPath(path, cwd);
|
|
4042
|
+
}
|
|
4043
|
+
case "edit": {
|
|
4044
|
+
const path = pickKeys(args, ["file_path", "path"]);
|
|
4045
|
+
return path === null ? null : displayPath(path, cwd);
|
|
4046
|
+
}
|
|
4047
|
+
case "ast_edit": {
|
|
4048
|
+
const path = firstPath(args, "paths");
|
|
4049
|
+
return path === null ? null : displayPath(path, cwd);
|
|
4050
|
+
}
|
|
4051
|
+
case "grep":
|
|
4052
|
+
case "glob":
|
|
4053
|
+
case "ast_grep": {
|
|
4054
|
+
const subject = queriesSubject(args) ?? pickKeys(args, [
|
|
4055
|
+
"query",
|
|
4056
|
+
"pattern",
|
|
4057
|
+
"pat",
|
|
4058
|
+
"url",
|
|
4059
|
+
"path"
|
|
4060
|
+
]);
|
|
4061
|
+
return subject === null ? null : displayPath(subject, cwd);
|
|
4062
|
+
}
|
|
4063
|
+
default: return null;
|
|
4064
|
+
}
|
|
4065
|
+
}
|
|
4066
|
+
/**
|
|
4067
|
+
* The generic card's collapsed summary: the fact the call itself states.
|
|
4068
|
+
* @param toolName - the call's wire tool name (empty when truncated).
|
|
4069
|
+
* @param args - the call's parsed arguments, or `null` when its head is gone.
|
|
4070
|
+
* @param cwd - the session workspace root, for shortening an absolute path.
|
|
4071
|
+
* @param t - the card translate seat.
|
|
4072
|
+
* @param raw - the call's original argument text, for a payload that is not
|
|
4073
|
+
* valid JSON yet (a call still streaming its arguments) or whose only values
|
|
4074
|
+
* are non-strings.
|
|
4075
|
+
* @returns the collapsed summary text.
|
|
4076
|
+
*/
|
|
4077
|
+
function fallbackCardSummary(toolName, args, cwd, t, raw = null) {
|
|
4078
|
+
const stated = statedFact(toolName, args, cwd);
|
|
4079
|
+
if (stated !== null) return stated;
|
|
4080
|
+
if (args !== null) {
|
|
4081
|
+
for (const value of Object.values(args)) if (typeof value === "string" && value !== "") return firstLine(value);
|
|
4082
|
+
}
|
|
4083
|
+
const text = raw === null || raw === "" ? null : firstLine(raw);
|
|
4084
|
+
if (text !== null && text !== "") return text;
|
|
4085
|
+
return argsSummary(args, t);
|
|
4086
|
+
}
|
|
4087
|
+
/**
|
|
4088
|
+
* Everything from the first colon is a read selector, not part of a filename.
|
|
4089
|
+
* The colon after a Windows drive letter is not one, and a URL is not a session
|
|
4090
|
+
* file at all.
|
|
4091
|
+
* @param value - the path argument, verbatim.
|
|
4092
|
+
* @returns the file the path names, or `null` when it names no openable file.
|
|
4093
|
+
*/
|
|
4094
|
+
function stripSelector(value) {
|
|
4095
|
+
if (/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(value)) return null;
|
|
4096
|
+
const start = /^[a-zA-Z]:[\\/]/.test(value) ? 2 : 0;
|
|
4097
|
+
const colon = value.indexOf(":", start);
|
|
4098
|
+
const base = colon === -1 ? value : value.slice(0, colon);
|
|
4099
|
+
return base === "" ? null : base;
|
|
4100
|
+
}
|
|
4101
|
+
/**
|
|
4102
|
+
* The real file a degraded file-backed row may offer to open — `null` when the
|
|
4103
|
+
* call names no single file.
|
|
4104
|
+
*
|
|
4105
|
+
* The head states the call verbatim (selector included) while the link has to
|
|
4106
|
+
* name a real file: the same split the read card itself makes between its
|
|
4107
|
+
* summary and its link. Whether that file then previews is the side bar's
|
|
4108
|
+
* decision, never this module's.
|
|
4109
|
+
* @param toolName - the call's wire tool name.
|
|
4110
|
+
* @param args - the call's parsed arguments, or `null`.
|
|
4111
|
+
* @returns the file to open, or `null` when there is nothing to open.
|
|
4112
|
+
*/
|
|
4113
|
+
function fallbackCardLink(toolName, args) {
|
|
4114
|
+
switch (toolName) {
|
|
4115
|
+
case "read": {
|
|
4116
|
+
const asked = pickKeys(args, ["path", "file_path"]);
|
|
4117
|
+
return asked === null ? null : stripSelector(asked);
|
|
4118
|
+
}
|
|
4119
|
+
case "write": return pickKeys(args, ["path", "file_path"]);
|
|
4120
|
+
case "edit": return pickKeys(args, ["file_path", "path"]);
|
|
4121
|
+
case "ast_edit": return firstPath(args, "paths");
|
|
4122
|
+
default: return null;
|
|
4123
|
+
}
|
|
4124
|
+
}
|
|
4125
|
+
//#endregion
|
|
3791
4126
|
//#region src/web/client/ToolCardShell.tsx
|
|
3792
4127
|
/**
|
|
3793
4128
|
* The shared card shell every row renders through.
|
|
3794
4129
|
*
|
|
3795
4130
|
* The shipped `ToolRow` is not reusable from a plugin (ui-tool is not part of
|
|
3796
4131
|
* the client platform baseline), so this is our own: one 24px header line
|
|
3797
|
-
* (
|
|
4132
|
+
* (tool glyph + title + separator + ellipsized summary + optional `+N -M`
|
|
3798
4133
|
* suffix + clickable path), a keyboard-reachable disclosure, and a body that
|
|
3799
|
-
* is either the card a row built or the flattened result text.
|
|
4134
|
+
* is either the card a row built or the flattened result text. The leading
|
|
4135
|
+
* glyph gives way to a state dot on a failed or interrupted call, and the row
|
|
4136
|
+
* sweeps while the call runs, as the shipped row does.
|
|
3800
4137
|
*
|
|
3801
4138
|
* Two properties matter more than the visuals:
|
|
3802
4139
|
* - **Never throw.** Every value is coerced defensively, and {@link CardBoundary}
|
|
@@ -3808,11 +4145,45 @@ window.__ModuleLoader__.load({
|
|
|
3808
4145
|
* both come out right.
|
|
3809
4146
|
* @module @xiaoso/dsh-tool-plus/web/client/ToolCardShell
|
|
3810
4147
|
*/
|
|
4148
|
+
/** Leading glyphs (the shipped table): every glyph renders at 14 inside the 16px leading box. */
|
|
4149
|
+
const LEADING_GLYPHS = {
|
|
4150
|
+
bash: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconApiOutline14, { size: 14 }),
|
|
4151
|
+
read: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconBrowseOutline16, { size: 14 }),
|
|
4152
|
+
edit: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEditOutline16, { size: 14 }),
|
|
4153
|
+
search: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSearchOutline16, { size: 14 }),
|
|
4154
|
+
others: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSparkle16, { size: 14 })
|
|
4155
|
+
};
|
|
4156
|
+
/**
|
|
4157
|
+
* The leading mark of one row: the tool's glyph while the call is clean or
|
|
4158
|
+
* running, and the state dot a failure or an interrupt swaps in — the shipped
|
|
4159
|
+
* `leadingFor` rule, so a failed row gives up its identity for the state
|
|
4160
|
+
* exactly where the shipped row does.
|
|
4161
|
+
* @param state - the card's run state.
|
|
4162
|
+
* @param toolName - the call's wire tool name, when the node carries one.
|
|
4163
|
+
* @returns the node the leading box draws.
|
|
4164
|
+
*/
|
|
4165
|
+
function leadingFor(state, toolName) {
|
|
4166
|
+
switch (leadingKind(state)) {
|
|
4167
|
+
case "error": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, { state: "error" });
|
|
4168
|
+
case "warning": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, { state: "warning" });
|
|
4169
|
+
default: return LEADING_GLYPHS[leadingGlyph(toolName)];
|
|
4170
|
+
}
|
|
4171
|
+
}
|
|
3811
4172
|
/** Chrome CSS, keyed by `data-plugin-css` and injected once per page. */
|
|
3812
4173
|
const CSS = `
|
|
3813
4174
|
.twc-root{display:flex;flex-direction:column;min-width:0}
|
|
3814
|
-
|
|
4175
|
+
/* The sweep's own anchor and clip, repeated from the shipped sheet so the band
|
|
4176
|
+
cannot escape the row if the shared row chrome ever drops them. */
|
|
4177
|
+
.twc-row{position:relative;min-width:0;overflow:hidden}
|
|
3815
4178
|
.twc-leading{flex-shrink:0}
|
|
4179
|
+
/* Running sweep — the shipped row's own treatment (ui-tool/ToolRow.module.css),
|
|
4180
|
+
copied band for band: a 300px glare of the theme background glides from
|
|
4181
|
+
off-left to off-right, washing the glyph and the text toward the background
|
|
4182
|
+
as it passes. Same anchor as the shipped sheet puts it on: DisclosureRow's
|
|
4183
|
+
own row already carries the position:relative and the overflow:hidden that
|
|
4184
|
+
clips the band. */
|
|
4185
|
+
.twc-root[data-state='running'] .twc-row::after{content:'';position:absolute;top:0;bottom:0;left:0;width:300px;background:linear-gradient(90deg,transparent 0%,color-mix(in srgb, var(--dsw-alias-bg-base) 60%, transparent) 55%,transparent 100%);animation:twc-row-sweep 2.6s ease-out infinite;pointer-events:none}
|
|
4186
|
+
@keyframes twc-row-sweep{0%{left:-300px}90%,100%{left:100%}}
|
|
3816
4187
|
.twc-chevron{color:var(--dsw-alias-label-secondary)}
|
|
3817
4188
|
.twc-title{font-weight:400}
|
|
3818
4189
|
.twc-sep{flex:none;width:2px;height:2px;border-radius:1px;margin:0 8px;background:var(--dsw-alias-label-caption)}
|
|
@@ -3878,8 +4249,11 @@ window.__ModuleLoader__.load({
|
|
|
3878
4249
|
.twc-root:hover .twc-inspect,.twc-inspect:focus-visible{opacity:1}
|
|
3879
4250
|
.twc-inspect:hover{background:var(--dsw-alias-interactive-bg-hover-solid);color:var(--dsw-alias-label-primary)}
|
|
3880
4251
|
.twc-visuallyHidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
|
|
3881
|
-
|
|
3882
|
-
|
|
4252
|
+
/* Motion is feedback, never decoration: the running sweep is the one animation
|
|
4253
|
+
this shell borrows from the shipped row, which runs it with no motion query
|
|
4254
|
+
at all. A reduced-motion reader loses only the glide — the state itself is
|
|
4255
|
+
still announced through the visually-hidden status word. */
|
|
4256
|
+
@media (prefers-reduced-motion: reduce){.twc-inspect{transition:none}.twc-root[data-state='running'] .twc-row::after{display:none}}
|
|
3883
4257
|
`;
|
|
3884
4258
|
/** Inject the card stylesheet once per page; the loader drops plugin style tags on unload. */
|
|
3885
4259
|
let cssInjected = false;
|
|
@@ -3906,7 +4280,7 @@ window.__ModuleLoader__.load({
|
|
|
3906
4280
|
*/
|
|
3907
4281
|
function ToolCardShell(props) {
|
|
3908
4282
|
injectCss();
|
|
3909
|
-
const { t, state, title, children, filePath, openFile, inspect } = props;
|
|
4283
|
+
const { t, state, title, children, filePath, openFile, inspect, tool } = props;
|
|
3910
4284
|
const [expanded, setExpanded] = (0, react.useState)(props.defaultOpen === true);
|
|
3911
4285
|
const bodyCard = hasContent(children) ? children : null;
|
|
3912
4286
|
const bodyText = typeof props.text === "string" && props.text !== "" ? props.text : null;
|
|
@@ -3937,7 +4311,7 @@ window.__ModuleLoader__.load({
|
|
|
3937
4311
|
}),
|
|
3938
4312
|
fileLink ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3939
4313
|
type: "button",
|
|
3940
|
-
className: "twc-fileLink",
|
|
4314
|
+
className: errorTone ? "twc-fileLink twc-errorSummary" : "twc-fileLink",
|
|
3941
4315
|
onClick: openPath,
|
|
3942
4316
|
onKeyDown: openPathKeyDown,
|
|
3943
4317
|
children: summaryText
|
|
@@ -3962,7 +4336,7 @@ window.__ModuleLoader__.load({
|
|
|
3962
4336
|
leadingClassName: "twc-leading",
|
|
3963
4337
|
titleClassName: "twc-title",
|
|
3964
4338
|
chevronClassName: "twc-chevron",
|
|
3965
|
-
icon:
|
|
4339
|
+
icon: leadingFor(state, tool),
|
|
3966
4340
|
title,
|
|
3967
4341
|
open,
|
|
3968
4342
|
expandable,
|
|
@@ -3991,20 +4365,24 @@ window.__ModuleLoader__.load({
|
|
|
3991
4365
|
* A card is only drawn once its metadata passed a `narrow*` guard, so anything
|
|
3992
4366
|
* else — a running call, a window-truncated call, a Code Dispatch child, a
|
|
3993
4367
|
* failure, a payload from another plugin version — lands here with the call's
|
|
3994
|
-
* own title, run state,
|
|
4368
|
+
* own title, run state, the fact its arguments state, and result text.
|
|
3995
4369
|
* @param props - see {@link GenericCardProps}.
|
|
3996
4370
|
* @returns the generic shell.
|
|
3997
4371
|
*/
|
|
3998
|
-
function GenericCard({ t, title, block, args, inspect }) {
|
|
4372
|
+
function GenericCard({ t, title, block, args, toolName, cwd, openFile, inspect }) {
|
|
3999
4373
|
const state = cardState(block);
|
|
4000
4374
|
const output = resultText(block);
|
|
4001
4375
|
const failure = state === "error" ? firstLine(output) : "";
|
|
4376
|
+
const link = failure === "" ? fallbackCardLink(toolName, args) : null;
|
|
4002
4377
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolCardShell, {
|
|
4003
4378
|
t,
|
|
4004
4379
|
state,
|
|
4005
4380
|
title,
|
|
4006
|
-
|
|
4381
|
+
tool: toolName,
|
|
4382
|
+
summary: failure === "" ? fallbackCardSummary(toolName, args, cwd, t, cardArgsRaw(block)) : failure,
|
|
4007
4383
|
summaryTone: failure === "" ? "default" : "error",
|
|
4384
|
+
filePath: link,
|
|
4385
|
+
openFile: link === null ? void 0 : openFile,
|
|
4008
4386
|
text: output,
|
|
4009
4387
|
inspect
|
|
4010
4388
|
});
|
|
@@ -4054,76 +4432,6 @@ window.__ModuleLoader__.load({
|
|
|
4054
4432
|
}
|
|
4055
4433
|
};
|
|
4056
4434
|
//#endregion
|
|
4057
|
-
//#region src/web/client/rows/command-card-facts.ts
|
|
4058
|
-
/**
|
|
4059
|
-
* Collapsed-fact builders for the two command-shaped cards: the command a
|
|
4060
|
-
* `bash` description hides, and the rewrite rule an `ast_edit` preview only
|
|
4061
|
-
* shows once expanded.
|
|
4062
|
-
*
|
|
4063
|
-
* Both cards collapse to one head line. `bash`'s head used to be the model's
|
|
4064
|
-
* own `description` — a sentence about intent, never the command that ran — so
|
|
4065
|
-
* the only way to learn what executed was to expand the card. `ast_edit`'s head
|
|
4066
|
-
* names the file and the replacement count, and its body previews the *result*:
|
|
4067
|
-
* the rule that produced that result lives only in the call's `ops` argument,
|
|
4068
|
-
* which no card showed at all. Each builder recovers one fact from the call's
|
|
4069
|
-
* own arguments, so nothing is inferred from output, and a call head that fell
|
|
4070
|
-
* outside the session window degrades to the facts the card already holds.
|
|
4071
|
-
* @module @xiaoso/dsh-tool-plus/web/client/rows/command-card-facts
|
|
4072
|
-
*/
|
|
4073
|
-
/** Whether `value` is a plain object — the only op shape the engine sends. */
|
|
4074
|
-
function isRecord$1(value) {
|
|
4075
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4076
|
-
}
|
|
4077
|
-
/**
|
|
4078
|
-
* The `bash` card's collapsed summary: what ran, placed after the sentence
|
|
4079
|
-
* saying why.
|
|
4080
|
-
*
|
|
4081
|
-
* The command is the fact the head must carry, so the description can never be
|
|
4082
|
-
* the whole summary — it is a prefix at most. Only its first line is used: a
|
|
4083
|
-
* summary is one row high, and the rest of a multi-line command belongs to the
|
|
4084
|
-
* expanded body, which draws the whole thing.
|
|
4085
|
-
* @param description - the model's one-line intent, or `null` when absent.
|
|
4086
|
-
* @param command - the command actually executed (never empty).
|
|
4087
|
-
* @param outcome - the interruption word (`timedOut` / `cancelled`), or `null`.
|
|
4088
|
-
* @returns the outcome alone when the run was interrupted; otherwise the
|
|
4089
|
-
* description joined to the command's first line, or that line alone.
|
|
4090
|
-
*/
|
|
4091
|
-
function bashCardSummary(description, command, outcome) {
|
|
4092
|
-
if (outcome !== null && outcome !== "") return outcome;
|
|
4093
|
-
const intent = description === null ? "" : description.trim();
|
|
4094
|
-
const line = firstLine(command);
|
|
4095
|
-
return intent === "" ? line : `${intent} · ${line}`;
|
|
4096
|
-
}
|
|
4097
|
-
/**
|
|
4098
|
-
* The `ast_edit` card's rule line: the first usable `ops` entry, written the
|
|
4099
|
-
* way the tool's own `ops` argument writes it (`pat → out`).
|
|
4100
|
-
*
|
|
4101
|
-
* Only the first rule is stated, with the count of the entries behind it: the
|
|
4102
|
-
* card exists to preview one change, and a call may carry many rules whose
|
|
4103
|
-
* patterns are whole AST fragments — listing them would bury the preview. The
|
|
4104
|
-
* remaining count is the array tail, not the number of *usable* entries, so it
|
|
4105
|
-
* always describes the call as it was made.
|
|
4106
|
-
* @param args - the call's parsed arguments, or `null` when its head is gone.
|
|
4107
|
-
* @param t - this plugin's card translate seat.
|
|
4108
|
-
* @returns the rule line, or `null` when the call carries no usable rule.
|
|
4109
|
-
*/
|
|
4110
|
-
function astEditRuleLine(args, t) {
|
|
4111
|
-
const ops = args?.ops;
|
|
4112
|
-
if (!Array.isArray(ops)) return null;
|
|
4113
|
-
for (let index = 0; index < ops.length; index += 1) {
|
|
4114
|
-
const op = ops[index];
|
|
4115
|
-
if (!isRecord$1(op)) continue;
|
|
4116
|
-
const pat = argText(op, "pat");
|
|
4117
|
-
if (pat === null) continue;
|
|
4118
|
-
const replacement = op.out;
|
|
4119
|
-
if (typeof replacement !== "string") continue;
|
|
4120
|
-
const rest = ops.length - 1;
|
|
4121
|
-
const rule = `${t("astEdit.rules")}: ${pat} →${replacement === "" ? "" : ` ${replacement}`}`;
|
|
4122
|
-
return rest === 0 ? rule : `${rule} · ${t("astEdit.rulesRest", { count: rest })}`;
|
|
4123
|
-
}
|
|
4124
|
-
return null;
|
|
4125
|
-
}
|
|
4126
|
-
//#endregion
|
|
4127
4435
|
//#region src/web/client/rows/AstEditRow.tsx
|
|
4128
4436
|
/**
|
|
4129
4437
|
* `ast_edit` row: the engine's own change preview.
|
|
@@ -4161,7 +4469,7 @@ window.__ModuleLoader__.load({
|
|
|
4161
4469
|
* @returns the preview card.
|
|
4162
4470
|
*/
|
|
4163
4471
|
function AstEditCard(props) {
|
|
4164
|
-
const { t, block, cwd, inspect, openFile, title } = props;
|
|
4472
|
+
const { t, block, cwd, inspect, openFile, title, toolName } = props;
|
|
4165
4473
|
const args = parseCardArgs(block);
|
|
4166
4474
|
const meta = narrowAstEditCardMeta(cardMeta(block));
|
|
4167
4475
|
if (isSubCall(block) || block.isError === true || meta === null || meta.preview === "") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GenericCard, {
|
|
@@ -4169,6 +4477,9 @@ window.__ModuleLoader__.load({
|
|
|
4169
4477
|
title,
|
|
4170
4478
|
block,
|
|
4171
4479
|
args,
|
|
4480
|
+
toolName,
|
|
4481
|
+
cwd,
|
|
4482
|
+
openFile,
|
|
4172
4483
|
inspect
|
|
4173
4484
|
});
|
|
4174
4485
|
const files = meta.files.length;
|
|
@@ -4181,6 +4492,7 @@ window.__ModuleLoader__.load({
|
|
|
4181
4492
|
t,
|
|
4182
4493
|
state: cardState(block),
|
|
4183
4494
|
title,
|
|
4495
|
+
tool: toolName,
|
|
4184
4496
|
summary,
|
|
4185
4497
|
summarySuffix: `${t("astEdit.replacements", { count: meta.replacements })} · ${t("astEdit.files", { count: files })}`,
|
|
4186
4498
|
filePath: single,
|
|
@@ -4243,7 +4555,7 @@ window.__ModuleLoader__.load({
|
|
|
4243
4555
|
* @returns the diff card.
|
|
4244
4556
|
*/
|
|
4245
4557
|
function FileMutationCard(props) {
|
|
4246
|
-
const { t, block, cwd, inspect, openFile, title } = props;
|
|
4558
|
+
const { t, block, cwd, inspect, openFile, title, toolName } = props;
|
|
4247
4559
|
const args = parseCardArgs(block);
|
|
4248
4560
|
const meta = narrowEditCardMeta(cardMeta(block));
|
|
4249
4561
|
const replaceForm = replaceHunks(args);
|
|
@@ -4252,6 +4564,9 @@ window.__ModuleLoader__.load({
|
|
|
4252
4564
|
title,
|
|
4253
4565
|
block,
|
|
4254
4566
|
args,
|
|
4567
|
+
toolName,
|
|
4568
|
+
cwd,
|
|
4569
|
+
openFile,
|
|
4255
4570
|
inspect
|
|
4256
4571
|
});
|
|
4257
4572
|
const diffs = meta === null ? replaceForm ?? [] : meta.diffs;
|
|
@@ -4263,6 +4578,7 @@ window.__ModuleLoader__.load({
|
|
|
4263
4578
|
t,
|
|
4264
4579
|
state: cardState(block),
|
|
4265
4580
|
title,
|
|
4581
|
+
tool: toolName,
|
|
4266
4582
|
summary,
|
|
4267
4583
|
summarySuffix: `+${totals.added} -${totals.removed}`,
|
|
4268
4584
|
filePath: single,
|
|
@@ -4410,43 +4726,6 @@ window.__ModuleLoader__.load({
|
|
|
4410
4726
|
};
|
|
4411
4727
|
}
|
|
4412
4728
|
//#endregion
|
|
4413
|
-
//#region src/web/client/rows/read-card-facts.ts
|
|
4414
|
-
/**
|
|
4415
|
-
* Collapsed-summary facts for the `read` card.
|
|
4416
|
-
*
|
|
4417
|
-
* The Host projection strips the inline selector off the path
|
|
4418
|
-
* (`stripReadSelector` in `web/host/read.ts`) because the card's *link* must
|
|
4419
|
-
* point at a real file, and it keeps only the file's own window. The collapsed
|
|
4420
|
-
* head is then the one place where the question the model actually asked is
|
|
4421
|
-
* still readable — and the projected path cannot answer it: a windowed read of
|
|
4422
|
-
* `package.json:22-25,31-34` and a whole-file read of `package.json` project to
|
|
4423
|
-
* the very same string, so the card hides the difference.
|
|
4424
|
-
*
|
|
4425
|
-
* The summary is therefore built from the call's own argument, selector and
|
|
4426
|
-
* all, with the projected path kept as the fallback for a result whose call
|
|
4427
|
-
* head fell outside the session window (a truncated window carries no
|
|
4428
|
-
* `tool/call` event, so no argument survives). That fallback states a fact the
|
|
4429
|
-
* card already holds; nothing is invented.
|
|
4430
|
-
* @module @xiaoso/dsh-tool-plus/web/client/rows/read-card-facts
|
|
4431
|
-
*/
|
|
4432
|
-
/**
|
|
4433
|
-
* The `read` card's collapsed summary: the path the model asked for, keeping
|
|
4434
|
-
* whatever inline selector it carried (`:22-25`, `:raw`, `:conflicts`, `:28-`,
|
|
4435
|
-
* a sqlite row, an archive member) and shortened against the workspace root.
|
|
4436
|
-
*
|
|
4437
|
-
* The selector is deliberately not validated against the read grammar: the head
|
|
4438
|
-
* reports the call verbatim, and a selector this plugin does not recognize is
|
|
4439
|
-
* still what the model typed — substituting the projection's stripped path
|
|
4440
|
-
* would erase the evidence that two calls differ.
|
|
4441
|
-
* @param args - the call's parsed arguments, or `null` when its head is gone.
|
|
4442
|
-
* @param metaPath - the Host-projected path (already selector-free).
|
|
4443
|
-
* @param cwd - the session workspace root, when known.
|
|
4444
|
-
* @returns the workspace-shortened argument path, or the projected path.
|
|
4445
|
-
*/
|
|
4446
|
-
function readCardSummary(args, metaPath, cwd) {
|
|
4447
|
-
return displayPath(argText(args, "path") ?? metaPath, cwd);
|
|
4448
|
-
}
|
|
4449
|
-
//#endregion
|
|
4450
4729
|
//#region src/web/client/rows/ReadRow.tsx
|
|
4451
4730
|
/**
|
|
4452
4731
|
* `read` row: a line-numbered window view, or the image the read returned.
|
|
@@ -4491,7 +4770,7 @@ window.__ModuleLoader__.load({
|
|
|
4491
4770
|
* @returns the read card.
|
|
4492
4771
|
*/
|
|
4493
4772
|
function ReadCard(props) {
|
|
4494
|
-
const { t, block, cwd, inspect, openFile, title } = props;
|
|
4773
|
+
const { t, block, cwd, inspect, openFile, title, toolName } = props;
|
|
4495
4774
|
const args = parseCardArgs(block);
|
|
4496
4775
|
const meta = narrowReadCardMeta(cardMeta(block));
|
|
4497
4776
|
const material = (0, react.useMemo)(() => imageCardMaterial(block, cwd), [block, cwd]);
|
|
@@ -4500,6 +4779,9 @@ window.__ModuleLoader__.load({
|
|
|
4500
4779
|
title,
|
|
4501
4780
|
block,
|
|
4502
4781
|
args,
|
|
4782
|
+
toolName,
|
|
4783
|
+
cwd,
|
|
4784
|
+
openFile,
|
|
4503
4785
|
inspect
|
|
4504
4786
|
});
|
|
4505
4787
|
if (meta === null) {
|
|
@@ -4508,6 +4790,9 @@ window.__ModuleLoader__.load({
|
|
|
4508
4790
|
title,
|
|
4509
4791
|
block,
|
|
4510
4792
|
args,
|
|
4793
|
+
toolName,
|
|
4794
|
+
cwd,
|
|
4795
|
+
openFile,
|
|
4511
4796
|
inspect
|
|
4512
4797
|
});
|
|
4513
4798
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ImageReadCard, {
|
|
@@ -4515,6 +4800,7 @@ window.__ModuleLoader__.load({
|
|
|
4515
4800
|
block,
|
|
4516
4801
|
material,
|
|
4517
4802
|
title,
|
|
4803
|
+
toolName,
|
|
4518
4804
|
inspect,
|
|
4519
4805
|
openFile,
|
|
4520
4806
|
loadImage: props.loadImage
|
|
@@ -4524,6 +4810,7 @@ window.__ModuleLoader__.load({
|
|
|
4524
4810
|
t,
|
|
4525
4811
|
state: cardState(block),
|
|
4526
4812
|
title,
|
|
4813
|
+
tool: toolName,
|
|
4527
4814
|
summary: readCardSummary(args, meta.path, cwd),
|
|
4528
4815
|
filePath: meta.path,
|
|
4529
4816
|
filePathLine: meta.offset,
|
|
@@ -4568,13 +4855,14 @@ window.__ModuleLoader__.load({
|
|
|
4568
4855
|
* @param props - see {@link ImageReadCardProps}.
|
|
4569
4856
|
* @returns the image card.
|
|
4570
4857
|
*/
|
|
4571
|
-
function ImageReadCard({ t, block, material, title, inspect, openFile, loadImage }) {
|
|
4858
|
+
function ImageReadCard({ t, block, material, title, toolName, inspect, openFile, loadImage }) {
|
|
4572
4859
|
const images = material.images;
|
|
4573
4860
|
const text = resultText(block);
|
|
4574
4861
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(ToolCardShell, {
|
|
4575
4862
|
t,
|
|
4576
4863
|
state: cardState(block),
|
|
4577
4864
|
title,
|
|
4865
|
+
tool: toolName,
|
|
4578
4866
|
summary: material.label,
|
|
4579
4867
|
filePath: material.path,
|
|
4580
4868
|
openFile,
|
|
@@ -4848,7 +5136,7 @@ window.__ModuleLoader__.load({
|
|
|
4848
5136
|
* @returns the search card.
|
|
4849
5137
|
*/
|
|
4850
5138
|
function SearchCard(props) {
|
|
4851
|
-
const { t, block, cwd, inspect, title } = props;
|
|
5139
|
+
const { t, block, cwd, inspect, title, toolName } = props;
|
|
4852
5140
|
const args = parseCardArgs(block);
|
|
4853
5141
|
const meta = narrowSearchCardMeta(cardMeta(block));
|
|
4854
5142
|
if (isSubCall(block) || block.isError === true || meta === null) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GenericCard, {
|
|
@@ -4856,6 +5144,8 @@ window.__ModuleLoader__.load({
|
|
|
4856
5144
|
title,
|
|
4857
5145
|
block,
|
|
4858
5146
|
args,
|
|
5147
|
+
toolName,
|
|
5148
|
+
cwd,
|
|
4859
5149
|
inspect
|
|
4860
5150
|
});
|
|
4861
5151
|
const subject = argText(args, "pattern") ?? argText(args, "pat") ?? argText(args, "path");
|
|
@@ -4864,6 +5154,7 @@ window.__ModuleLoader__.load({
|
|
|
4864
5154
|
t,
|
|
4865
5155
|
state: cardState(block),
|
|
4866
5156
|
title,
|
|
5157
|
+
tool: toolName,
|
|
4867
5158
|
summary: subject ?? argsSummary(args, t),
|
|
4868
5159
|
summarySuffix: searchCardSuffix(args, meta, cwd, t),
|
|
4869
5160
|
inspect,
|
|
@@ -4922,7 +5213,7 @@ window.__ModuleLoader__.load({
|
|
|
4922
5213
|
* @returns the terminal card or the generic shell.
|
|
4923
5214
|
*/
|
|
4924
5215
|
function TerminalCard(props) {
|
|
4925
|
-
const { t, block, cwd: sessionCwd, home, inspect, title } = props;
|
|
5216
|
+
const { t, block, cwd: sessionCwd, home, inspect, title, toolName } = props;
|
|
4926
5217
|
const args = parseCardArgs(block);
|
|
4927
5218
|
const meta = narrowTerminalCardMeta(cardMeta(block));
|
|
4928
5219
|
const command = argText(args, "command");
|
|
@@ -4932,12 +5223,15 @@ window.__ModuleLoader__.load({
|
|
|
4932
5223
|
title,
|
|
4933
5224
|
block,
|
|
4934
5225
|
args,
|
|
5226
|
+
toolName,
|
|
5227
|
+
cwd: sessionCwd,
|
|
4935
5228
|
inspect
|
|
4936
5229
|
});
|
|
4937
5230
|
if (meta !== null && meta.mode === "background") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolCardShell, {
|
|
4938
5231
|
t,
|
|
4939
5232
|
state,
|
|
4940
5233
|
title,
|
|
5234
|
+
tool: toolName,
|
|
4941
5235
|
summary: t("bash.background", { jobId: meta.jobId }),
|
|
4942
5236
|
text: resultText(block),
|
|
4943
5237
|
inspect
|
|
@@ -4955,6 +5249,7 @@ window.__ModuleLoader__.load({
|
|
|
4955
5249
|
t,
|
|
4956
5250
|
state,
|
|
4957
5251
|
title,
|
|
5252
|
+
tool: toolName,
|
|
4958
5253
|
summary,
|
|
4959
5254
|
inspect,
|
|
4960
5255
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.TerminalBlock, {
|
|
@@ -5006,7 +5301,7 @@ window.__ModuleLoader__.load({
|
|
|
5006
5301
|
* @returns the preview card.
|
|
5007
5302
|
*/
|
|
5008
5303
|
function WriteCard(props) {
|
|
5009
|
-
const { t, block, cwd, inspect, openFile, title } = props;
|
|
5304
|
+
const { t, block, cwd, inspect, openFile, title, toolName } = props;
|
|
5010
5305
|
const args = parseCardArgs(block);
|
|
5011
5306
|
const meta = narrowWriteCardMeta(cardMeta(block));
|
|
5012
5307
|
const content = argText(args, "content");
|
|
@@ -5016,6 +5311,9 @@ window.__ModuleLoader__.load({
|
|
|
5016
5311
|
title,
|
|
5017
5312
|
block,
|
|
5018
5313
|
args,
|
|
5314
|
+
toolName,
|
|
5315
|
+
cwd,
|
|
5316
|
+
openFile,
|
|
5019
5317
|
inspect
|
|
5020
5318
|
});
|
|
5021
5319
|
const lines = t("write.lines", { count: lineCount(content) });
|
|
@@ -5025,6 +5323,7 @@ window.__ModuleLoader__.load({
|
|
|
5025
5323
|
t,
|
|
5026
5324
|
state: cardState(block),
|
|
5027
5325
|
title,
|
|
5326
|
+
tool: toolName,
|
|
5028
5327
|
summary: displayPath(path, cwd),
|
|
5029
5328
|
summarySuffix: lines + skip,
|
|
5030
5329
|
filePath: path,
|
package/lib/index.mjs
CHANGED
|
@@ -3,7 +3,7 @@ __installBunShim();
|
|
|
3
3
|
import { n as fs_promises_shim_exports, t as exists } from "./fs-promises-shim-Bx0fpxuk.mjs";
|
|
4
4
|
import { i as setRuntimeLogger, n as systemChromiumCandidatesForTest, r as runtimeLogger } from "./launch-Uq7920ng.mjs";
|
|
5
5
|
import { $ as isEnoent, A as formatCount, C as warn, D as installBunShim, F as $flag, N as $env, O as formatAge, P as $envpos, Q as hasFsCode, U as getAutoQaDbPath, V as VERSION, X as getRemoteDir, Y as getPuppeteerDir, at as findOnPath, b as debug, c as combineSignals, d as $which, et as isEnotdir, it as untilAborted, k as formatBytes$1, l as exec, m as readImageMetadata, nt as peekFile, q as getInstallId, tt as isProbablyBinary, u as render, x as error } from "./src-DUUqyo9y.mjs";
|
|
6
|
-
import { C as truncateToWidth$1, S as replaceTabs, _ as formatCodeFrameLine, a as fetchBinary, b as LRUCache, c as getParallelExtractContent, d as convertFileWithMarkit, f as Settings, g as capParseErrors, h as OMP_DEFAULTS, i as convertWithMarkit, l as ensureTool, m as settings, o as extractWithParallel, p as isSettingsInitialized, s as findParallelApiKey, u as CONVERTIBLE_EXTENSIONS, v as formatParseErrors, x as padding, y as shortenPath } from "./utils-
|
|
6
|
+
import { C as truncateToWidth$1, S as replaceTabs, _ as formatCodeFrameLine, a as fetchBinary, b as LRUCache, c as getParallelExtractContent, d as convertFileWithMarkit, f as Settings, g as capParseErrors, h as OMP_DEFAULTS, i as convertWithMarkit, l as ensureTool, m as settings, o as extractWithParallel, p as isSettingsInitialized, s as findParallelApiKey, u as CONVERTIBLE_EXTENSIONS, v as formatParseErrors, x as padding, y as shortenPath } from "./utils-CdKv-8uE.mjs";
|
|
7
7
|
import { t as sanitizeText } from "./sanitize-text-BCf5KmCf.mjs";
|
|
8
8
|
import { n as isRecord$5 } from "./type-guards-CttAANEx.mjs";
|
|
9
9
|
import { n as ToolError, r as throwIfAborted, t as ToolAbortError } from "./tool-errors-DoyxivAR.mjs";
|
|
@@ -10317,7 +10317,7 @@ let specialHandlersPromise;
|
|
|
10317
10317
|
* requires a special handler, so we keep them out of the cold-startup graph.
|
|
10318
10318
|
*/
|
|
10319
10319
|
function loadSpecialHandlers() {
|
|
10320
|
-
specialHandlersPromise ??= import("./scrapers-
|
|
10320
|
+
specialHandlersPromise ??= import("./scrapers-BWgeG8qC.mjs").then((m) => m.specialHandlers);
|
|
10321
10321
|
return specialHandlersPromise;
|
|
10322
10322
|
}
|
|
10323
10323
|
/**
|
|
@@ -3,7 +3,7 @@ __installBunShim();
|
|
|
3
3
|
import { n as fs_promises_shim_exports } from "./fs-promises-shim-Bx0fpxuk.mjs";
|
|
4
4
|
import { $ as isEnoent, B as USER_AGENT, C as warn, G as getDocsRsCacheDir, N as $env, c as combineSignals, j as formatNumber, k as formatBytes, l as exec, s as Snowflake, y as parseFrontmatter } from "./src-DUUqyo9y.mjs";
|
|
5
5
|
import { W as tryParseJson } from "./utils-BMmwLB0f.mjs";
|
|
6
|
-
import { a as fetchBinary, c as getParallelExtractContent, i as convertWithMarkit, l as ensureTool, m as settings, n as asRecord, o as extractWithParallel, r as asString, s as findParallelApiKey, t as asNumber } from "./utils-
|
|
6
|
+
import { a as fetchBinary, c as getParallelExtractContent, i as convertWithMarkit, l as ensureTool, m as settings, n as asRecord, o as extractWithParallel, r as asString, s as findParallelApiKey, t as asNumber } from "./utils-CdKv-8uE.mjs";
|
|
7
7
|
import { n as isRecord } from "./type-guards-CttAANEx.mjs";
|
|
8
8
|
import { r as throwIfAborted, t as ToolAbortError } from "./tool-errors-DoyxivAR.mjs";
|
|
9
9
|
import { c as getLocalizedText, d as looksLikeHtml, i as decodeHtmlEntities, l as htmlToBasicMarkdown, o as formatIsoDate, r as buildResult, s as formatMediaDuration, u as loadPage } from "./types-DT9vgZ3S.mjs";
|
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
*
|
|
4
4
|
* The shipped `ToolRow` is not reusable from a plugin (ui-tool is not part of
|
|
5
5
|
* the client platform baseline), so this is our own: one 24px header line
|
|
6
|
-
* (
|
|
6
|
+
* (tool glyph + title + separator + ellipsized summary + optional `+N -M`
|
|
7
7
|
* suffix + clickable path), a keyboard-reachable disclosure, and a body that
|
|
8
|
-
* is either the card a row built or the flattened result text.
|
|
8
|
+
* is either the card a row built or the flattened result text. The leading
|
|
9
|
+
* glyph gives way to a state dot on a failed or interrupted call, and the row
|
|
10
|
+
* sweeps while the call runs, as the shipped row does.
|
|
9
11
|
*
|
|
10
12
|
* Two properties matter more than the visuals:
|
|
11
13
|
* - **Never throw.** Every value is coerced defensively, and {@link CardBoundary}
|
|
@@ -23,8 +25,10 @@ import { type CardBlockView, type CardOpenFileOptions, type CardState, type Card
|
|
|
23
25
|
export interface ToolCardShellProps {
|
|
24
26
|
/** Card translate seat. */
|
|
25
27
|
t: CardTranslate;
|
|
26
|
-
/** Run state driving the leading
|
|
28
|
+
/** Run state driving the leading mark and the status word. */
|
|
27
29
|
state: CardState;
|
|
30
|
+
/** Wire tool name selecting the leading glyph; absent/unknown = the generic glyph. */
|
|
31
|
+
tool?: string | null | undefined;
|
|
28
32
|
/** Single-line title (the tool name). */
|
|
29
33
|
title: string;
|
|
30
34
|
/** Collapsed summary after the separator; empty renders no separator. */
|
|
@@ -64,6 +68,12 @@ export interface GenericCardProps {
|
|
|
64
68
|
block: CardBlockView;
|
|
65
69
|
/** The call's parsed arguments, when there are any. */
|
|
66
70
|
args: Record<string, unknown> | null;
|
|
71
|
+
/** Wire tool name selecting the leading glyph; absent/unknown = the generic glyph. */
|
|
72
|
+
toolName?: string | null | undefined;
|
|
73
|
+
/** Session workspace root, so a stated path is shortened the rows' way. */
|
|
74
|
+
cwd?: string | undefined;
|
|
75
|
+
/** Opens the call's file in the host's viewer; absent = the path is plain text. */
|
|
76
|
+
openFile?: ((path: string, options?: CardOpenFileOptions) => void) | undefined;
|
|
67
77
|
/** Jump to this call in the trajectory view. */
|
|
68
78
|
inspect?: (() => void) | undefined;
|
|
69
79
|
}
|
|
@@ -73,11 +83,11 @@ export interface GenericCardProps {
|
|
|
73
83
|
* A card is only drawn once its metadata passed a `narrow*` guard, so anything
|
|
74
84
|
* else — a running call, a window-truncated call, a Code Dispatch child, a
|
|
75
85
|
* failure, a payload from another plugin version — lands here with the call's
|
|
76
|
-
* own title, run state,
|
|
86
|
+
* own title, run state, the fact its arguments state, and result text.
|
|
77
87
|
* @param props - see {@link GenericCardProps}.
|
|
78
88
|
* @returns the generic shell.
|
|
79
89
|
*/
|
|
80
|
-
export declare function GenericCard({ t, title, block, args, inspect }: GenericCardProps): import("react").JSX.Element;
|
|
90
|
+
export declare function GenericCard({ t, title, block, args, toolName, cwd, openFile, inspect }: GenericCardProps): import("react").JSX.Element;
|
|
81
91
|
/** Props of {@link CardBoundary}. */
|
|
82
92
|
export interface CardBoundaryProps {
|
|
83
93
|
/** Card translate seat, forwarded to the fallback shell. */
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
/** Locale namespace of the tool-card bundle (registered by `registerToolCards`). */
|
|
18
18
|
export declare const CARD_LOCALE_NS = "tool-plus-cards";
|
|
19
19
|
/** Every copy key of the tool-card namespace. */
|
|
20
|
-
export type ToolCardLocaleKey = 'copy' | 'copied' | 'collapse' | 'expand' | 'collapseAria' | 'expandAria' | 'expandRest' | 'files.one' | 'files.other' | 'running' | 'done' | 'failed' | 'cancelled' | 'timedOut' | 'noOutput' | 'title.bash' | 'title.read' | 'title.write' | 'title.edit' | 'title.grep' | 'title.glob' | 'title.astGrep' | 'title.astEdit' | 'write.lines' | 'write.madeExecutable' | 'astEdit.replacements' | 'astEdit.files' | 'astEdit.parseErrors' | 'astEdit.rules' | 'astEdit.rulesRest' | 'read.window' | 'read.collapseAria' | 'read.expandAria' | 'read.expandRest' | 'search.paths' | 'search.paths.truncated' | 'search.matches' | 'search.matches.truncated' | 'search.noResults' | 'search.scope' | 'search.collapseAria' | 'search.expandAria' | 'search.expandRest' | 'terminal.signal' | 'terminal.exitCode' | 'terminal.running' | 'terminal.failed' | 'terminal.done' | 'terminal.noOutput' | 'bash.background' | 'image.loading' | 'image.loadFailed' | 'image.open' | 'image.openNamed' | 'image.dialog' | 'image.close' | 'image.unnamed' | 'image.caption' | 'generic.params' | 'generic.noDetail' | 'inspect';
|
|
20
|
+
export type ToolCardLocaleKey = 'copy' | 'copied' | 'collapse' | 'expand' | 'collapseAria' | 'expandAria' | 'expandRest' | 'files.one' | 'files.other' | 'running' | 'done' | 'failed' | 'stopped' | 'cancelled' | 'timedOut' | 'noOutput' | 'title.bash' | 'title.read' | 'title.write' | 'title.edit' | 'title.grep' | 'title.glob' | 'title.astGrep' | 'title.astEdit' | 'write.lines' | 'write.madeExecutable' | 'astEdit.replacements' | 'astEdit.files' | 'astEdit.parseErrors' | 'astEdit.rules' | 'astEdit.rulesRest' | 'read.window' | 'read.collapseAria' | 'read.expandAria' | 'read.expandRest' | 'search.paths' | 'search.paths.truncated' | 'search.matches' | 'search.matches.truncated' | 'search.noResults' | 'search.scope' | 'search.collapseAria' | 'search.expandAria' | 'search.expandRest' | 'terminal.signal' | 'terminal.exitCode' | 'terminal.running' | 'terminal.failed' | 'terminal.done' | 'terminal.noOutput' | 'bash.background' | 'image.loading' | 'image.loadFailed' | 'image.open' | 'image.openNamed' | 'image.dialog' | 'image.close' | 'image.unnamed' | 'image.caption' | 'generic.params' | 'generic.noDetail' | 'inspect';
|
|
21
21
|
/** Simplified Chinese copy (the source dictionary). */
|
|
22
22
|
export declare const zh: Record<ToolCardLocaleKey, string>;
|
|
23
23
|
/** English dictionary, checked complete against the zh key set. */
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* nothing here touches a raw `meta` field directly.
|
|
15
15
|
* @module @xiaoso/dsh-tool-plus/web/client/row-utils
|
|
16
16
|
*/
|
|
17
|
-
import type { DiffBlockLabels, ReadBlockLabels, SearchBlockLabels,
|
|
17
|
+
import type { DiffBlockLabels, ReadBlockLabels, SearchBlockLabels, TerminalBlockLabels } from '@deepseek-ai/dsh-client-ui-primitives';
|
|
18
18
|
import type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots';
|
|
19
19
|
import type { CARD_LOCALE_NS, ToolCardLocaleKey } from './labels.ts';
|
|
20
20
|
/** Translate seat of this plugin's card namespace. */
|
|
@@ -36,12 +36,30 @@ export interface CardBlockView {
|
|
|
36
36
|
} | null;
|
|
37
37
|
readonly content?: unknown;
|
|
38
38
|
readonly isError?: unknown;
|
|
39
|
+
/**
|
|
40
|
+
* Settled failure detail. A turn stopped mid-call is projected as a settled
|
|
41
|
+
* `isError` block carrying `code: 'interrupted'`, which is a stop, not a
|
|
42
|
+
* failure — the shipped row model reads this before `isError`.
|
|
43
|
+
*/
|
|
44
|
+
readonly error?: unknown;
|
|
39
45
|
readonly meta?: unknown;
|
|
40
46
|
}
|
|
41
47
|
/** Card run state, one step off the shipped `ToolRowState` (no `stopped`). */
|
|
42
48
|
export type CardState = 'running' | 'ok' | 'error' | 'warning';
|
|
43
49
|
/** Whether a block is the settled half of a call pair. */
|
|
44
50
|
export declare function isSettled(block: CardBlockView): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* The call's original argument text.
|
|
53
|
+
*
|
|
54
|
+
* A running call carries it directly; a settled result carries the head
|
|
55
|
+
* backfilled from the in-window `tool/call`, which is absent when window
|
|
56
|
+
* truncation left that event outside. The text outlives the parse: a call whose
|
|
57
|
+
* arguments are still streaming is not valid JSON yet, and the shell states its
|
|
58
|
+
* first line rather than pretending the call said nothing.
|
|
59
|
+
* @param block - the frozen running-or-settled call node.
|
|
60
|
+
* @returns the argument text, or `''` when no head survives.
|
|
61
|
+
*/
|
|
62
|
+
export declare function cardArgsRaw(block: CardBlockView): string;
|
|
45
63
|
/**
|
|
46
64
|
* Parse the call's raw argument JSON.
|
|
47
65
|
*
|
|
@@ -55,17 +73,19 @@ export declare function parseCardArgs(block: CardBlockView): Record<string, unkn
|
|
|
55
73
|
/**
|
|
56
74
|
* Run state of one call.
|
|
57
75
|
*
|
|
58
|
-
* A
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
76
|
+
* A turn stopped mid-call is projected as a settled `isError` block carrying
|
|
77
|
+
* `error.code === 'interrupted'`; the shipped row model reads that before
|
|
78
|
+
* `isError`, so a stopped call is amber and named "stopped" rather than failed.
|
|
79
|
+
* Any other settled `isError` result is an error. A foreground command that
|
|
80
|
+
* timed out or was cancelled is amber rather than green (the shipped terminal
|
|
81
|
+
* model reads only the trailing exit marker, which is exactly what the card
|
|
82
|
+
* owner was told not to trust). A non-zero exit stays `ok`: bash reports a
|
|
83
|
+
* failing command as result data, and the card's own status pill carries the
|
|
84
|
+
* red.
|
|
63
85
|
* @param block - the frozen running-or-settled call node.
|
|
64
86
|
* @returns the card run state.
|
|
65
87
|
*/
|
|
66
88
|
export declare function cardState(block: CardBlockView): CardState;
|
|
67
|
-
/** Map a card run state onto the primitive's dot semantics. */
|
|
68
|
-
export declare function dotState(state: CardState): StateDotState;
|
|
69
89
|
/**
|
|
70
90
|
* The assistive-technology status word for a run state, or `null` when the
|
|
71
91
|
* state is already carried by the row's content.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Row-leading treatment: which glyph a row leads with, and what replaces it
|
|
3
|
+
* when the call did not settle cleanly.
|
|
4
|
+
*
|
|
5
|
+
* The shipped `ToolRow` does not lead with a status dot. A clean or running row
|
|
6
|
+
* leads with its tool's own glyph, and only `error` / `stopped` swap that glyph
|
|
7
|
+
* for a `StateDot` (`ui-tool/src/client/tool/components/ToolRow.tsx::leadingFor`);
|
|
8
|
+
* the glyph per tool name comes from the shipped variant table
|
|
9
|
+
* (`ui-tool/src/client/tool/toolviews/GenericToolCard.tsx::VARIANT_ICONS`).
|
|
10
|
+
* This module is that rule and that table, kept pure so the mapping is testable
|
|
11
|
+
* under the Node runner — the component that draws it lives in
|
|
12
|
+
* `ToolCardShell`.
|
|
13
|
+
*
|
|
14
|
+
* Two of the eight card keys are this plugin's own tools, so they are absent
|
|
15
|
+
* from the shipped name table. They take the family whose shipped glyph
|
|
16
|
+
* describes the act — a structural search reads like `grep`, an atomic edit
|
|
17
|
+
* writes like `edit` — rather than the shipped `others` sparkle, which would
|
|
18
|
+
* make the two cards this plugin is the only home of look like unknown tools.
|
|
19
|
+
* @module @xiaoso/dsh-tool-plus/web/client/rows/card-leading
|
|
20
|
+
*/
|
|
21
|
+
import type { CardState } from '../row-utils.ts';
|
|
22
|
+
/** Glyph families of the shipped leading table. */
|
|
23
|
+
export type CardLeadingGlyph = 'bash' | 'read' | 'edit' | 'search' | 'others';
|
|
24
|
+
/**
|
|
25
|
+
* Glyph family a row leads with.
|
|
26
|
+
* @param toolName - the call's wire tool name, when the node carries one.
|
|
27
|
+
* @returns the family, or `others` (the shipped generic glyph) for an unknown name.
|
|
28
|
+
*/
|
|
29
|
+
export declare function leadingGlyph(toolName: string | null | undefined): CardLeadingGlyph;
|
|
30
|
+
/** What the leading box draws for one run state. */
|
|
31
|
+
export type CardLeadingKind = 'glyph' | 'error' | 'warning';
|
|
32
|
+
/**
|
|
33
|
+
* Whether a run state keeps the row's glyph or replaces it with a state dot.
|
|
34
|
+
* @param state - the card's run state.
|
|
35
|
+
* @returns the leading kind; `error` and `warning` are the two dot states.
|
|
36
|
+
*/
|
|
37
|
+
export declare function leadingKind(state: CardState): CardLeadingKind;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collapsed-summary facts for the generic card — every row's degradation path.
|
|
3
|
+
*
|
|
4
|
+
* A call lands on the generic shell when its own card cannot be built: it is
|
|
5
|
+
* still running, its result carried no text, its metadata fell outside the
|
|
6
|
+
* session window, it is a Code Dispatch child, or the Host projected an
|
|
7
|
+
* interruption the card has no material for. In every one of those cases the
|
|
8
|
+
* call's ARGUMENTS are the only material left, and the shipped generic row
|
|
9
|
+
* answers them with the call's own fact: its variant's summary keys first, then
|
|
10
|
+
* ANY string the payload carries, then the first line of the raw argument text
|
|
11
|
+
* (`deriveSummary` in ui-tool's `tool-call-model.ts`). It never answers with an
|
|
12
|
+
* argument count.
|
|
13
|
+
*
|
|
14
|
+
* That is the rule here. The count it replaces told the reader nothing: a
|
|
15
|
+
* directory read, a `:raw` window, a running `grep` and a child call all
|
|
16
|
+
* collapsed to "1 个参数" — the one thing a degraded row must not do, since the
|
|
17
|
+
* head is then the only place the fact exists.
|
|
18
|
+
*
|
|
19
|
+
* The key preference follows THIS plugin's own tool schemas rather than the
|
|
20
|
+
* shipped `SUMMARY_KEYS`: our tools replaced the built-in ones with the OMP
|
|
21
|
+
* native parameter names (`read`/`write` take `path`, `ast_grep` takes `pat`,
|
|
22
|
+
* `ast_edit` takes `paths`), and the shipped table's `file_path` is what the
|
|
23
|
+
* built-in tools used. Both spellings are accepted, ours first, so a transcript
|
|
24
|
+
* recorded before the takeover still states its path.
|
|
25
|
+
* @module @xiaoso/dsh-tool-plus/web/client/rows/fallback-card-facts
|
|
26
|
+
*/
|
|
27
|
+
import { type CardTranslate } from '../row-utils.ts';
|
|
28
|
+
/**
|
|
29
|
+
* The generic card's collapsed summary: the fact the call itself states.
|
|
30
|
+
* @param toolName - the call's wire tool name (empty when truncated).
|
|
31
|
+
* @param args - the call's parsed arguments, or `null` when its head is gone.
|
|
32
|
+
* @param cwd - the session workspace root, for shortening an absolute path.
|
|
33
|
+
* @param t - the card translate seat.
|
|
34
|
+
* @param raw - the call's original argument text, for a payload that is not
|
|
35
|
+
* valid JSON yet (a call still streaming its arguments) or whose only values
|
|
36
|
+
* are non-strings.
|
|
37
|
+
* @returns the collapsed summary text.
|
|
38
|
+
*/
|
|
39
|
+
export declare function fallbackCardSummary(toolName: string | null | undefined, args: Record<string, unknown> | null, cwd: string | undefined, t: CardTranslate, raw?: string | null): string;
|
|
40
|
+
/**
|
|
41
|
+
* The real file a degraded file-backed row may offer to open — `null` when the
|
|
42
|
+
* call names no single file.
|
|
43
|
+
*
|
|
44
|
+
* The head states the call verbatim (selector included) while the link has to
|
|
45
|
+
* name a real file: the same split the read card itself makes between its
|
|
46
|
+
* summary and its link. Whether that file then previews is the side bar's
|
|
47
|
+
* decision, never this module's.
|
|
48
|
+
* @param toolName - the call's wire tool name.
|
|
49
|
+
* @param args - the call's parsed arguments, or `null`.
|
|
50
|
+
* @returns the file to open, or `null` when there is nothing to open.
|
|
51
|
+
*/
|
|
52
|
+
export declare function fallbackCardLink(toolName: string | null | undefined, args: Record<string, unknown> | null): string | null;
|
|
@@ -6267,7 +6267,7 @@ const settings = {
|
|
|
6267
6267
|
};
|
|
6268
6268
|
//#endregion
|
|
6269
6269
|
//#region package.json
|
|
6270
|
-
var version = "0.1.8-beta.
|
|
6270
|
+
var version = "0.1.8-beta.4";
|
|
6271
6271
|
/** `.tmp` files older than this are treated as orphaned writes and swept. */
|
|
6272
6272
|
const TMP_ORPHAN_MAX_AGE_MS = 3e5;
|
|
6273
6273
|
function markitConversionCacheKey(bytes, extension) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xiaoso/dsh-tool-plus",
|
|
3
3
|
"description": "Oh My Pi bash runtime ported as a deepseek-harness tool plugin: persistent shell session, output minimizer, managed background jobs, command interception",
|
|
4
|
-
"version": "0.1.8-beta.
|
|
4
|
+
"version": "0.1.8-beta.4",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"deepseek-harness",
|
package/presets/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xiaoso/dsh-tool-plus-presets",
|
|
3
|
-
"version": "0.1.8-beta.
|
|
3
|
+
"version": "0.1.8-beta.4",
|
|
4
4
|
"description": "Agent-preset installer for dsh-tool-plus: installs the standard / PTC enhanced preset templates into a DeepSeek Harness home.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|