@theokit/sdk-tools 0.9.1 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/dist/index.cjs +55 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -4
- package/dist/index.d.ts +38 -4
- package/dist/index.js +55 -8
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -576,6 +576,29 @@ interface CreateReadFileToolOptions {
|
|
|
576
576
|
}
|
|
577
577
|
declare function createReadFileTool(opts: CreateReadFileToolOptions): CustomTool;
|
|
578
578
|
|
|
579
|
+
/**
|
|
580
|
+
* SE37 — the public reasoning toolkit: `ReasoningTools.create()` returns a
|
|
581
|
+
* `think` + `analyze` scratchpad (no-side-effect tools that echo the model's
|
|
582
|
+
* structured reasoning back as an observation, so the ReAct loop feeds it
|
|
583
|
+
* forward). Mirrors Anthropic's "think" tool + Agno's `ReasoningTools`.
|
|
584
|
+
*
|
|
585
|
+
* Lives in `@theokit/sdk-tools` (not core) so the full toolkit stays out of the
|
|
586
|
+
* core bundle. The `reasoning: true` agent flag auto-attaches an equivalent
|
|
587
|
+
* lean `think` from core; add these explicitly (`tools: [...ReasoningTools.create()]`)
|
|
588
|
+
* when you want the model to reason with a scratchpad on any model.
|
|
589
|
+
*
|
|
590
|
+
* @public
|
|
591
|
+
*/
|
|
592
|
+
|
|
593
|
+
/** Reasoning scratchpad tools. `ReasoningTools.create()` → `[think, analyze]`. */
|
|
594
|
+
declare class ReasoningTools {
|
|
595
|
+
private constructor();
|
|
596
|
+
/** Build the tools. Pass `{ analyze: false }` for `think` only. */
|
|
597
|
+
static create(opts?: {
|
|
598
|
+
analyze?: boolean;
|
|
599
|
+
}): CustomTool[];
|
|
600
|
+
}
|
|
601
|
+
|
|
579
602
|
/**
|
|
580
603
|
* `run_vitest` — built-in tool for coding agents.
|
|
581
604
|
*
|
|
@@ -685,6 +708,11 @@ declare function createShellTool(opts: CreateShellToolOptions): CustomTool;
|
|
|
685
708
|
* - remove(id) → remove an item
|
|
686
709
|
* - list() → show all items with status
|
|
687
710
|
* - clear_completed() → remove all done items
|
|
711
|
+
*
|
|
712
|
+
* #119 — state is keyed by `ctx.threadId` (the run's session identity, injected by the
|
|
713
|
+
* SDK from `Agent.getOrCreate(sessionId, …)`). One tool object served to many sessions
|
|
714
|
+
* from a single process keeps each session's list isolated. When no `threadId` is present
|
|
715
|
+
* (single-session CLI usage) every call shares one default session — behavior unchanged.
|
|
688
716
|
*/
|
|
689
717
|
interface TodoItem {
|
|
690
718
|
id: string;
|
|
@@ -697,9 +725,15 @@ interface TodolistTool {
|
|
|
697
725
|
name: string;
|
|
698
726
|
description: string;
|
|
699
727
|
inputSchema: unknown;
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
728
|
+
/**
|
|
729
|
+
* #119 — the optional 2nd `ctx` carries the run's `threadId`; state is scoped to it.
|
|
730
|
+
* Single-argument callers (CLI / tests) share one default session.
|
|
731
|
+
*/
|
|
732
|
+
handler: (input: TodoInput, ctx?: {
|
|
733
|
+
threadId?: string;
|
|
734
|
+
}) => string;
|
|
735
|
+
/** Expose a session's items for testing (defaults to the no-threadId session). */
|
|
736
|
+
getItems: (threadId?: string) => TodoItem[];
|
|
703
737
|
}
|
|
704
738
|
type TodoInput = {
|
|
705
739
|
action: "add";
|
|
@@ -930,4 +964,4 @@ interface CreateWriteFileToolOptions {
|
|
|
930
964
|
}
|
|
931
965
|
declare function createWriteFileTool(opts: CreateWriteFileToolOptions): CustomTool;
|
|
932
966
|
|
|
933
|
-
export { CatastrophicCommandError, type CommandPolicy, type CreateApplyPatchToolOptions, type CreateBraveWebSearchAdapterOptions, type CreateEditFileToolOptions, type CreateGenericHttpSearchAdapterOptions, type CreateGitDiffToolOptions, type CreateGlobToolOptions, type CreateListDirToolOptions, type CreateReadFileToolOptions, type CreateRunVitestToolOptions, type CreateSearchTextToolOptions, type CreateShellToolOptions, type CreateWebFetchToolOptions, type CreateWebSearchToolOptions, type CreateWriteFileToolOptions, DEFAULT_TOOL_GUIDANCE, type EnvContextOptions, type PlanModeTool, type PlanModeToolOptions, type PlanModeToolWithStore, type PlanNode, type QuestionTool, type QuestionToolOptions, ReadTracker, RedirectBlockedError, type RepoMapOptions, type ResolveAndScreenOptions, type ScreenedFetchOptions, type SessionArtifactStore, type SessionArtifactStoreOptions, SsrfBlockedError, type TodoItem, type TodolistTool, type ToolGuidanceMap, type TruncationOptions, type TruncationResult, type VitestSummary, type WebSearchCallback, type WebSearchResult, buildEnvContext, buildRepoMap, catastrophicShellReason, commandDenialReason, createApplyPatchTool, createBraveWebSearchAdapter, createEditFileTool, createGenericHttpSearchAdapter, createGitDiffTool, createGlobTool, createListDirTool, createPlanModeTool, createQuestionTool, createReadFileTool, createRunVitestTool, createSearchTextTool, createSessionArtifactStore, createShellTool, createTodolistTool, createWebFetchTool, createWebSearchTool, createWriteFileTool, denyCatastrophicCommands, formatCode, formatDiff, formatError, formatFileList, injectGuidance, isBlockedIp, isCommandAllowed, renderToolList, resolveAndScreen, screenedFetch, todoItemsToPlanNodes, truncateOutput, withDefaultGuidance, withDescription, withShellExitGuidance, withToolResultGuidance };
|
|
967
|
+
export { CatastrophicCommandError, type CommandPolicy, type CreateApplyPatchToolOptions, type CreateBraveWebSearchAdapterOptions, type CreateEditFileToolOptions, type CreateGenericHttpSearchAdapterOptions, type CreateGitDiffToolOptions, type CreateGlobToolOptions, type CreateListDirToolOptions, type CreateReadFileToolOptions, type CreateRunVitestToolOptions, type CreateSearchTextToolOptions, type CreateShellToolOptions, type CreateWebFetchToolOptions, type CreateWebSearchToolOptions, type CreateWriteFileToolOptions, DEFAULT_TOOL_GUIDANCE, type EnvContextOptions, type PlanModeTool, type PlanModeToolOptions, type PlanModeToolWithStore, type PlanNode, type QuestionTool, type QuestionToolOptions, ReadTracker, ReasoningTools, RedirectBlockedError, type RepoMapOptions, type ResolveAndScreenOptions, type ScreenedFetchOptions, type SessionArtifactStore, type SessionArtifactStoreOptions, SsrfBlockedError, type TodoItem, type TodolistTool, type ToolGuidanceMap, type TruncationOptions, type TruncationResult, type VitestSummary, type WebSearchCallback, type WebSearchResult, buildEnvContext, buildRepoMap, catastrophicShellReason, commandDenialReason, createApplyPatchTool, createBraveWebSearchAdapter, createEditFileTool, createGenericHttpSearchAdapter, createGitDiffTool, createGlobTool, createListDirTool, createPlanModeTool, createQuestionTool, createReadFileTool, createRunVitestTool, createSearchTextTool, createSessionArtifactStore, createShellTool, createTodolistTool, createWebFetchTool, createWebSearchTool, createWriteFileTool, denyCatastrophicCommands, formatCode, formatDiff, formatError, formatFileList, injectGuidance, isBlockedIp, isCommandAllowed, renderToolList, resolveAndScreen, screenedFetch, todoItemsToPlanNodes, truncateOutput, withDefaultGuidance, withDescription, withShellExitGuidance, withToolResultGuidance };
|
package/dist/index.d.ts
CHANGED
|
@@ -576,6 +576,29 @@ interface CreateReadFileToolOptions {
|
|
|
576
576
|
}
|
|
577
577
|
declare function createReadFileTool(opts: CreateReadFileToolOptions): CustomTool;
|
|
578
578
|
|
|
579
|
+
/**
|
|
580
|
+
* SE37 — the public reasoning toolkit: `ReasoningTools.create()` returns a
|
|
581
|
+
* `think` + `analyze` scratchpad (no-side-effect tools that echo the model's
|
|
582
|
+
* structured reasoning back as an observation, so the ReAct loop feeds it
|
|
583
|
+
* forward). Mirrors Anthropic's "think" tool + Agno's `ReasoningTools`.
|
|
584
|
+
*
|
|
585
|
+
* Lives in `@theokit/sdk-tools` (not core) so the full toolkit stays out of the
|
|
586
|
+
* core bundle. The `reasoning: true` agent flag auto-attaches an equivalent
|
|
587
|
+
* lean `think` from core; add these explicitly (`tools: [...ReasoningTools.create()]`)
|
|
588
|
+
* when you want the model to reason with a scratchpad on any model.
|
|
589
|
+
*
|
|
590
|
+
* @public
|
|
591
|
+
*/
|
|
592
|
+
|
|
593
|
+
/** Reasoning scratchpad tools. `ReasoningTools.create()` → `[think, analyze]`. */
|
|
594
|
+
declare class ReasoningTools {
|
|
595
|
+
private constructor();
|
|
596
|
+
/** Build the tools. Pass `{ analyze: false }` for `think` only. */
|
|
597
|
+
static create(opts?: {
|
|
598
|
+
analyze?: boolean;
|
|
599
|
+
}): CustomTool[];
|
|
600
|
+
}
|
|
601
|
+
|
|
579
602
|
/**
|
|
580
603
|
* `run_vitest` — built-in tool for coding agents.
|
|
581
604
|
*
|
|
@@ -685,6 +708,11 @@ declare function createShellTool(opts: CreateShellToolOptions): CustomTool;
|
|
|
685
708
|
* - remove(id) → remove an item
|
|
686
709
|
* - list() → show all items with status
|
|
687
710
|
* - clear_completed() → remove all done items
|
|
711
|
+
*
|
|
712
|
+
* #119 — state is keyed by `ctx.threadId` (the run's session identity, injected by the
|
|
713
|
+
* SDK from `Agent.getOrCreate(sessionId, …)`). One tool object served to many sessions
|
|
714
|
+
* from a single process keeps each session's list isolated. When no `threadId` is present
|
|
715
|
+
* (single-session CLI usage) every call shares one default session — behavior unchanged.
|
|
688
716
|
*/
|
|
689
717
|
interface TodoItem {
|
|
690
718
|
id: string;
|
|
@@ -697,9 +725,15 @@ interface TodolistTool {
|
|
|
697
725
|
name: string;
|
|
698
726
|
description: string;
|
|
699
727
|
inputSchema: unknown;
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
728
|
+
/**
|
|
729
|
+
* #119 — the optional 2nd `ctx` carries the run's `threadId`; state is scoped to it.
|
|
730
|
+
* Single-argument callers (CLI / tests) share one default session.
|
|
731
|
+
*/
|
|
732
|
+
handler: (input: TodoInput, ctx?: {
|
|
733
|
+
threadId?: string;
|
|
734
|
+
}) => string;
|
|
735
|
+
/** Expose a session's items for testing (defaults to the no-threadId session). */
|
|
736
|
+
getItems: (threadId?: string) => TodoItem[];
|
|
703
737
|
}
|
|
704
738
|
type TodoInput = {
|
|
705
739
|
action: "add";
|
|
@@ -930,4 +964,4 @@ interface CreateWriteFileToolOptions {
|
|
|
930
964
|
}
|
|
931
965
|
declare function createWriteFileTool(opts: CreateWriteFileToolOptions): CustomTool;
|
|
932
966
|
|
|
933
|
-
export { CatastrophicCommandError, type CommandPolicy, type CreateApplyPatchToolOptions, type CreateBraveWebSearchAdapterOptions, type CreateEditFileToolOptions, type CreateGenericHttpSearchAdapterOptions, type CreateGitDiffToolOptions, type CreateGlobToolOptions, type CreateListDirToolOptions, type CreateReadFileToolOptions, type CreateRunVitestToolOptions, type CreateSearchTextToolOptions, type CreateShellToolOptions, type CreateWebFetchToolOptions, type CreateWebSearchToolOptions, type CreateWriteFileToolOptions, DEFAULT_TOOL_GUIDANCE, type EnvContextOptions, type PlanModeTool, type PlanModeToolOptions, type PlanModeToolWithStore, type PlanNode, type QuestionTool, type QuestionToolOptions, ReadTracker, RedirectBlockedError, type RepoMapOptions, type ResolveAndScreenOptions, type ScreenedFetchOptions, type SessionArtifactStore, type SessionArtifactStoreOptions, SsrfBlockedError, type TodoItem, type TodolistTool, type ToolGuidanceMap, type TruncationOptions, type TruncationResult, type VitestSummary, type WebSearchCallback, type WebSearchResult, buildEnvContext, buildRepoMap, catastrophicShellReason, commandDenialReason, createApplyPatchTool, createBraveWebSearchAdapter, createEditFileTool, createGenericHttpSearchAdapter, createGitDiffTool, createGlobTool, createListDirTool, createPlanModeTool, createQuestionTool, createReadFileTool, createRunVitestTool, createSearchTextTool, createSessionArtifactStore, createShellTool, createTodolistTool, createWebFetchTool, createWebSearchTool, createWriteFileTool, denyCatastrophicCommands, formatCode, formatDiff, formatError, formatFileList, injectGuidance, isBlockedIp, isCommandAllowed, renderToolList, resolveAndScreen, screenedFetch, todoItemsToPlanNodes, truncateOutput, withDefaultGuidance, withDescription, withShellExitGuidance, withToolResultGuidance };
|
|
967
|
+
export { CatastrophicCommandError, type CommandPolicy, type CreateApplyPatchToolOptions, type CreateBraveWebSearchAdapterOptions, type CreateEditFileToolOptions, type CreateGenericHttpSearchAdapterOptions, type CreateGitDiffToolOptions, type CreateGlobToolOptions, type CreateListDirToolOptions, type CreateReadFileToolOptions, type CreateRunVitestToolOptions, type CreateSearchTextToolOptions, type CreateShellToolOptions, type CreateWebFetchToolOptions, type CreateWebSearchToolOptions, type CreateWriteFileToolOptions, DEFAULT_TOOL_GUIDANCE, type EnvContextOptions, type PlanModeTool, type PlanModeToolOptions, type PlanModeToolWithStore, type PlanNode, type QuestionTool, type QuestionToolOptions, ReadTracker, ReasoningTools, RedirectBlockedError, type RepoMapOptions, type ResolveAndScreenOptions, type ScreenedFetchOptions, type SessionArtifactStore, type SessionArtifactStoreOptions, SsrfBlockedError, type TodoItem, type TodolistTool, type ToolGuidanceMap, type TruncationOptions, type TruncationResult, type VitestSummary, type WebSearchCallback, type WebSearchResult, buildEnvContext, buildRepoMap, catastrophicShellReason, commandDenialReason, createApplyPatchTool, createBraveWebSearchAdapter, createEditFileTool, createGenericHttpSearchAdapter, createGitDiffTool, createGlobTool, createListDirTool, createPlanModeTool, createQuestionTool, createReadFileTool, createRunVitestTool, createSearchTextTool, createSessionArtifactStore, createShellTool, createTodolistTool, createWebFetchTool, createWebSearchTool, createWriteFileTool, denyCatastrophicCommands, formatCode, formatDiff, formatError, formatFileList, injectGuidance, isBlockedIp, isCommandAllowed, renderToolList, resolveAndScreen, screenedFetch, todoItemsToPlanNodes, truncateOutput, withDefaultGuidance, withDescription, withShellExitGuidance, withToolResultGuidance };
|
package/dist/index.js
CHANGED
|
@@ -1433,6 +1433,37 @@ function evaluateReadBeforeWrite(tracker, path, currentMtimeMs) {
|
|
|
1433
1433
|
if (recorded !== currentMtimeMs) return "stale";
|
|
1434
1434
|
return "ok";
|
|
1435
1435
|
}
|
|
1436
|
+
var ReasoningTools = class {
|
|
1437
|
+
constructor() {
|
|
1438
|
+
}
|
|
1439
|
+
/** Build the tools. Pass `{ analyze: false }` for `think` only. */
|
|
1440
|
+
static create(opts) {
|
|
1441
|
+
const think = Tool.create({
|
|
1442
|
+
name: "think",
|
|
1443
|
+
description: "Use this as a scratchpad to think step by step BEFORE answering or acting. Write out your reasoning for one step. Nothing else happens \u2014 it is only your private reasoning space. Call it as many times as you need before the final answer.",
|
|
1444
|
+
inputSchema: z.object({
|
|
1445
|
+
thought: z.string().min(1, "think: `thought` must be a non-empty string.")
|
|
1446
|
+
}),
|
|
1447
|
+
handler: ({ thought }) => thought
|
|
1448
|
+
});
|
|
1449
|
+
if (opts?.analyze === false) return [think];
|
|
1450
|
+
const analyze = Tool.create({
|
|
1451
|
+
name: "analyze",
|
|
1452
|
+
description: "Analyze the result of a previous step or tool call. State what you looked at, your analysis, and whether to `continue` reasoning, `validate` (double-check) your work, or give the `final_answer`. Use this to catch your own mistakes before answering.",
|
|
1453
|
+
inputSchema: z.object({
|
|
1454
|
+
title: z.string().optional(),
|
|
1455
|
+
result: z.string().min(1, "analyze: `result` must describe what you are analyzing."),
|
|
1456
|
+
analysis: z.string().min(1, "analyze: `analysis` must contain your reasoning."),
|
|
1457
|
+
next_action: z.enum(["continue", "validate", "final_answer"])
|
|
1458
|
+
}),
|
|
1459
|
+
handler: ({ title, result, analysis, next_action }) => `${title ? `# ${title}
|
|
1460
|
+
` : ""}Result: ${result}
|
|
1461
|
+
Analysis: ${analysis}
|
|
1462
|
+
Next: ${next_action}`
|
|
1463
|
+
});
|
|
1464
|
+
return [think, analyze];
|
|
1465
|
+
}
|
|
1466
|
+
};
|
|
1436
1467
|
var DEFAULT_TIMEOUT_MS2 = 12e4;
|
|
1437
1468
|
var DEFAULT_MAX_STDOUT_BYTES2 = 10 * 1024 * 1024;
|
|
1438
1469
|
function createRunVitestTool(opts) {
|
|
@@ -1770,7 +1801,7 @@ function requireId(input) {
|
|
|
1770
1801
|
if (!("id" in input) || !input.id) return null;
|
|
1771
1802
|
return input.id;
|
|
1772
1803
|
}
|
|
1773
|
-
function
|
|
1804
|
+
function makeSessionOps() {
|
|
1774
1805
|
const items = [];
|
|
1775
1806
|
let nextId = 1;
|
|
1776
1807
|
function genId() {
|
|
@@ -1839,6 +1870,26 @@ ${done}/${items.length} done | ${inProg} in progress | ${pending} pending`);
|
|
|
1839
1870
|
list: () => listResult({}),
|
|
1840
1871
|
clear_completed: handleClearCompleted
|
|
1841
1872
|
};
|
|
1873
|
+
return {
|
|
1874
|
+
handle: (input) => {
|
|
1875
|
+
const action = actions[input.action];
|
|
1876
|
+
if (!action) return fail({ error: "invalid_action" });
|
|
1877
|
+
return action(input);
|
|
1878
|
+
},
|
|
1879
|
+
getItems: () => [...items]
|
|
1880
|
+
};
|
|
1881
|
+
}
|
|
1882
|
+
function createTodolistTool() {
|
|
1883
|
+
const sessions = /* @__PURE__ */ new Map();
|
|
1884
|
+
function ops(threadId) {
|
|
1885
|
+
const key = threadId ?? "__default__";
|
|
1886
|
+
let session = sessions.get(key);
|
|
1887
|
+
if (session === void 0) {
|
|
1888
|
+
session = makeSessionOps();
|
|
1889
|
+
sessions.set(key, session);
|
|
1890
|
+
}
|
|
1891
|
+
return session;
|
|
1892
|
+
}
|
|
1842
1893
|
return {
|
|
1843
1894
|
name: "todolist",
|
|
1844
1895
|
description: "Create and maintain a structured task list for the current session \u2014 tracks progress and keeps a multi-step plan visible across turns. Use it proactively when the work has 3+ steps or the user gave multiple tasks; skip it for a single trivial step. Keep exactly ONE item 'in_progress' at a time, and mark 'complete' only after the work is actually done. Actions: 'add' (create with title), 'in_progress' (mark started by id), 'complete' (mark done by id), 'remove' (delete by id), 'list' (show all), 'clear_completed' (remove done items). Returns { ok, items, items_summary } (items = structured array; items_summary = formatted text).",
|
|
@@ -1861,12 +1912,8 @@ ${done}/${items.length} done | ${inProg} in progress | ${pending} pending`);
|
|
|
1861
1912
|
},
|
|
1862
1913
|
required: ["action"]
|
|
1863
1914
|
},
|
|
1864
|
-
handler: (input) =>
|
|
1865
|
-
|
|
1866
|
-
if (!action) return fail({ error: "invalid_action" });
|
|
1867
|
-
return action(input);
|
|
1868
|
-
},
|
|
1869
|
-
getItems: () => [...items]
|
|
1915
|
+
handler: (input, ctx) => ops(ctx?.threadId).handle(input),
|
|
1916
|
+
getItems: (threadId) => ops(threadId).getItems()
|
|
1870
1917
|
};
|
|
1871
1918
|
}
|
|
1872
1919
|
function truncateOutput(output, opts) {
|
|
@@ -2192,6 +2239,6 @@ async function isBinaryFile(absolutePath) {
|
|
|
2192
2239
|
}
|
|
2193
2240
|
}
|
|
2194
2241
|
|
|
2195
|
-
export { CatastrophicCommandError, DEFAULT_TOOL_GUIDANCE, ReadTracker, RedirectBlockedError, SsrfBlockedError, buildEnvContext, buildRepoMap, catastrophicShellReason, commandDenialReason, createApplyPatchTool, createBraveWebSearchAdapter, createEditFileTool, createGenericHttpSearchAdapter, createGitDiffTool, createGlobTool, createListDirTool, createPlanModeTool, createQuestionTool, createReadFileTool, createRunVitestTool, createSearchTextTool, createSessionArtifactStore, createShellTool, createTodolistTool, createWebFetchTool, createWebSearchTool, createWriteFileTool, denyCatastrophicCommands, formatCode, formatDiff, formatError, formatFileList, injectGuidance, isBlockedIp, isCommandAllowed, renderToolList, resolveAndScreen, screenedFetch, todoItemsToPlanNodes, truncateOutput, withDefaultGuidance, withDescription, withShellExitGuidance, withToolResultGuidance };
|
|
2242
|
+
export { CatastrophicCommandError, DEFAULT_TOOL_GUIDANCE, ReadTracker, ReasoningTools, RedirectBlockedError, SsrfBlockedError, buildEnvContext, buildRepoMap, catastrophicShellReason, commandDenialReason, createApplyPatchTool, createBraveWebSearchAdapter, createEditFileTool, createGenericHttpSearchAdapter, createGitDiffTool, createGlobTool, createListDirTool, createPlanModeTool, createQuestionTool, createReadFileTool, createRunVitestTool, createSearchTextTool, createSessionArtifactStore, createShellTool, createTodolistTool, createWebFetchTool, createWebSearchTool, createWriteFileTool, denyCatastrophicCommands, formatCode, formatDiff, formatError, formatFileList, injectGuidance, isBlockedIp, isCommandAllowed, renderToolList, resolveAndScreen, screenedFetch, todoItemsToPlanNodes, truncateOutput, withDefaultGuidance, withDescription, withShellExitGuidance, withToolResultGuidance };
|
|
2196
2243
|
//# sourceMappingURL=index.js.map
|
|
2197
2244
|
//# sourceMappingURL=index.js.map
|