@agimon-ai/doompi-edit 0.0.1-alpha.44 → 0.0.1-alpha.47
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/package.json +20 -13
- package/dist/api-contracts.cjs +0 -1
- package/dist/api-contracts.d.cts +0 -2
- package/dist/api-contracts.d.mts +0 -2
- package/dist/api-contracts.mjs +0 -1
- package/dist/constants/package.cjs +0 -2
- package/dist/constants/package.cjs.map +0 -1
- package/dist/constants/package.mjs +0 -2
- package/dist/constants/package.mjs.map +0 -1
- package/dist/extensions/pi.cjs +0 -2
- package/dist/extensions/pi.cjs.map +0 -1
- package/dist/extensions/pi.d.cts +0 -5
- package/dist/extensions/pi.d.cts.map +0 -1
- package/dist/extensions/pi.d.mts +0 -5
- package/dist/extensions/pi.d.mts.map +0 -1
- package/dist/extensions/pi.mjs +0 -2
- package/dist/extensions/pi.mjs.map +0 -1
- package/dist/extensions/server.cjs +0 -2
- package/dist/extensions/server.cjs.map +0 -1
- package/dist/extensions/server.d.cts +0 -5
- package/dist/extensions/server.d.cts.map +0 -1
- package/dist/extensions/server.d.mts +0 -5
- package/dist/extensions/server.d.mts.map +0 -1
- package/dist/extensions/server.mjs +0 -2
- package/dist/extensions/server.mjs.map +0 -1
- package/dist/index.cjs +0 -1
- package/dist/index.d.cts +0 -5
- package/dist/index.d.mts +0 -5
- package/dist/index.mjs +0 -1
- package/dist/schemas/apiContracts.cjs +0 -2
- package/dist/schemas/apiContracts.cjs.map +0 -1
- package/dist/schemas/apiContracts.d.cts +0 -53
- package/dist/schemas/apiContracts.d.cts.map +0 -1
- package/dist/schemas/apiContracts.d.mts +0 -53
- package/dist/schemas/apiContracts.d.mts.map +0 -1
- package/dist/schemas/apiContracts.mjs +0 -2
- package/dist/schemas/apiContracts.mjs.map +0 -1
- package/dist/schemas/editTool.cjs +0 -2
- package/dist/schemas/editTool.cjs.map +0 -1
- package/dist/schemas/editTool.d.cts +0 -20
- package/dist/schemas/editTool.d.cts.map +0 -1
- package/dist/schemas/editTool.d.mts +0 -20
- package/dist/schemas/editTool.d.mts.map +0 -1
- package/dist/schemas/editTool.mjs +0 -2
- package/dist/schemas/editTool.mjs.map +0 -1
- package/dist/services/editTool/index.cjs +0 -9
- package/dist/services/editTool/index.cjs.map +0 -1
- package/dist/services/editTool/index.d.cts +0 -12
- package/dist/services/editTool/index.d.cts.map +0 -1
- package/dist/services/editTool/index.d.mts +0 -12
- package/dist/services/editTool/index.d.mts.map +0 -1
- package/dist/services/editTool/index.mjs +0 -9
- package/dist/services/editTool/index.mjs.map +0 -1
- package/dist/tools/headlessEdit.cjs +0 -2
- package/dist/tools/headlessEdit.cjs.map +0 -1
- package/dist/tools/headlessEdit.d.cts +0 -6
- package/dist/tools/headlessEdit.d.cts.map +0 -1
- package/dist/tools/headlessEdit.d.mts +0 -6
- package/dist/tools/headlessEdit.d.mts.map +0 -1
- package/dist/tools/headlessEdit.mjs +0 -2
- package/dist/tools/headlessEdit.mjs.map +0 -1
- package/dist/tools/piEdit.cjs +0 -2
- package/dist/tools/piEdit.cjs.map +0 -1
- package/dist/tools/piEdit.d.cts +0 -8
- package/dist/tools/piEdit.d.cts.map +0 -1
- package/dist/tools/piEdit.d.mts +0 -8
- package/dist/tools/piEdit.d.mts.map +0 -1
- package/dist/tools/piEdit.mjs +0 -2
- package/dist/tools/piEdit.mjs.map +0 -1
- package/src/extensions/web.ts +0 -14
- package/src/web/components/EditToolMessage.tsx +0 -121
- package/src/web/lib/editToolView.ts +0 -75
- package/src/web/tsconfig.json +0 -23
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agimon-ai/doompi-edit",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.47",
|
|
4
4
|
"description": "Snapshot-bound hashline edit tool for Pi and DoomPi.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -24,14 +24,12 @@
|
|
|
24
24
|
"directory": "packages/default/doompi-edit"
|
|
25
25
|
},
|
|
26
26
|
"files": [
|
|
27
|
-
"dist"
|
|
28
|
-
"src/web",
|
|
29
|
-
"src/extensions/web.ts",
|
|
30
|
-
"!src/web/**/*.stories.tsx"
|
|
27
|
+
"dist"
|
|
31
28
|
],
|
|
32
29
|
"type": "module",
|
|
33
30
|
"main": "./dist/index.cjs",
|
|
34
|
-
"
|
|
31
|
+
"module": "./dist/index.mjs",
|
|
32
|
+
"types": "./dist/index.d.cts",
|
|
35
33
|
"jsnext:main": "./dist/index.mjs",
|
|
36
34
|
"exports": {
|
|
37
35
|
".": {
|
|
@@ -39,6 +37,11 @@
|
|
|
39
37
|
"import": "./dist/index.mjs",
|
|
40
38
|
"require": "./dist/index.cjs"
|
|
41
39
|
},
|
|
40
|
+
"./api-contracts": {
|
|
41
|
+
"types": "./dist/api-contracts.d.mts",
|
|
42
|
+
"import": "./dist/api-contracts.mjs",
|
|
43
|
+
"require": "./dist/api-contracts.cjs"
|
|
44
|
+
},
|
|
42
45
|
"./extensions/pi": {
|
|
43
46
|
"types": "./dist/extensions/pi.d.mts",
|
|
44
47
|
"import": "./dist/extensions/pi.mjs",
|
|
@@ -49,20 +52,24 @@
|
|
|
49
52
|
"import": "./dist/extensions/server.mjs",
|
|
50
53
|
"require": "./dist/extensions/server.cjs"
|
|
51
54
|
},
|
|
55
|
+
"./extensions/web": {
|
|
56
|
+
"import": "./dist/extensions/web.mjs"
|
|
57
|
+
},
|
|
52
58
|
"./package.json": "./package.json"
|
|
53
59
|
},
|
|
54
60
|
"publishConfig": {
|
|
55
61
|
"access": "public"
|
|
56
62
|
},
|
|
57
63
|
"dependencies": {
|
|
58
|
-
"@agimon-ai/doompi-core": "0.0.1-alpha.
|
|
59
|
-
"@agimon-ai/doompi-hashline": "0.0.1-alpha.
|
|
60
|
-
"@agimon-ai/doompi-ui": "0.0.1-alpha.
|
|
61
|
-
"@agimon-ai/doompi-web-components": "0.0.1-alpha.
|
|
64
|
+
"@agimon-ai/doompi-core": "0.0.1-alpha.75",
|
|
65
|
+
"@agimon-ai/doompi-hashline": "0.0.1-alpha.44",
|
|
66
|
+
"@agimon-ai/doompi-ui": "0.0.1-alpha.75",
|
|
67
|
+
"@agimon-ai/doompi-web-components": "0.0.1-alpha.33",
|
|
62
68
|
"@deepseek-ai/cordis": "4.0.2",
|
|
63
69
|
"typebox": "1.3.30"
|
|
64
70
|
},
|
|
65
71
|
"devDependencies": {
|
|
72
|
+
"@agimon-ai/doompi-build": "0.0.1-alpha.4",
|
|
66
73
|
"@earendil-works/pi-coding-agent": "0.85.1",
|
|
67
74
|
"@earendil-works/pi-tui": "0.85.1",
|
|
68
75
|
"@tanstack/react-store": "0.11.1",
|
|
@@ -92,7 +99,7 @@
|
|
|
92
99
|
"node": ">=22.19.0"
|
|
93
100
|
},
|
|
94
101
|
"doompiServer": {
|
|
95
|
-
"entry": "./
|
|
102
|
+
"entry": "./generated/server.ts",
|
|
96
103
|
"dist": "./dist/extensions/server.mjs",
|
|
97
104
|
"scopes": [
|
|
98
105
|
"session"
|
|
@@ -105,7 +112,7 @@
|
|
|
105
112
|
"doompiWeb": {
|
|
106
113
|
"pluginId": "edit",
|
|
107
114
|
"channels": [],
|
|
108
|
-
"client": "./
|
|
115
|
+
"client": "./dist/extensions/web.mjs",
|
|
109
116
|
"scopes": [
|
|
110
117
|
"session"
|
|
111
118
|
]
|
|
@@ -118,7 +125,7 @@
|
|
|
118
125
|
"scripts": {
|
|
119
126
|
"build": "tsdown",
|
|
120
127
|
"test": "vitest --run",
|
|
121
|
-
"typecheck": "tsc --noEmit && tsc --noEmit -p
|
|
128
|
+
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.web.json",
|
|
122
129
|
"lint": "oxlint . && oxfmt . --check",
|
|
123
130
|
"fixcode": "oxlint . --fix && oxfmt ."
|
|
124
131
|
}
|
package/dist/api-contracts.cjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("./schemas/apiContracts.cjs");exports.apiContracts=e.apiContracts,exports.default=e.apiContracts;
|
package/dist/api-contracts.d.cts
DELETED
package/dist/api-contracts.d.mts
DELETED
package/dist/api-contracts.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{apiContracts as e}from"./schemas/apiContracts.mjs";export{e as apiContracts,e as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"package.cjs","names":[],"sources":["../../src/constants/package.ts"],"sourcesContent":["export const PACKAGE_SOURCE = '@agimon-ai/doompi-edit';\n"],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"package.mjs","names":[],"sources":["../../src/constants/package.ts"],"sourcesContent":["export const PACKAGE_SOURCE = '@agimon-ai/doompi-edit';\n"],"mappings":"AAAA,MAAa,EAAiB"}
|
package/dist/extensions/pi.cjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("../tools/piEdit.cjs"),t=require("../constants/package.cjs");let n=require("@agimon-ai/doompi-core/pi-extension");const r=(0,n.definePiExtension)(t.PACKAGE_SOURCE,()=>({toolOverrides:[{source:t.PACKAGE_SOURCE,tools:[`edit`],replacements:[(0,n.definePiTool)(e.createHashlineEditTool())]}]}));exports.activateDoomPiEditExtension=r,exports.default=r;
|
|
2
|
-
//# sourceMappingURL=pi.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pi.cjs","names":["definePiExtension","PACKAGE_SOURCE","definePiTool","createHashlineEditTool"],"sources":["../../src/extensions/pi.ts"],"sourcesContent":["import { definePiExtension, definePiTool } from '@agimon-ai/doompi-core/pi-extension';\n\nimport { PACKAGE_SOURCE } from '../constants/package';\nimport { createHashlineEditTool } from '../tools/piEdit';\n\nexport const activateDoomPiEditExtension = definePiExtension(PACKAGE_SOURCE, () => ({\n toolOverrides: [{ source: PACKAGE_SOURCE, tools: ['edit'], replacements: [definePiTool(createHashlineEditTool())] }],\n}));\nexport default activateDoomPiEditExtension;\n"],"mappings":"iOAKA,MAAa,GAAA,EAA8BA,EAAAA,kBAAAA,CAAkBC,EAAAA,oBAAuB,CAClF,cAAe,CAAC,CAAE,OAAQA,EAAAA,eAAgB,MAAO,CAAC,MAAM,EAAG,aAAc,EAAA,EAACC,EAAAA,aAAAA,CAAaC,EAAAA,uBAAuB,CAAC,CAAC,CAAE,CAAC,CACrH,EAAE"}
|
package/dist/extensions/pi.d.cts
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
//#region src/extensions/pi.d.ts
|
|
2
|
-
export declare const activateDoomPiEditExtension: import("@agimon-ai/doompi-core/runtime-pi-extension").DefinedPiExtension<undefined>;
|
|
3
|
-
//#endregion
|
|
4
|
-
export { activateDoomPiEditExtension as default };
|
|
5
|
-
//# sourceMappingURL=pi.d.cts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pi.d.cts","names":[],"sources":["../../src/extensions/pi.ts"],"mappings":";qBAKa,mFAA2B"}
|
package/dist/extensions/pi.d.mts
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
//#region src/extensions/pi.d.ts
|
|
2
|
-
export declare const activateDoomPiEditExtension: import("@agimon-ai/doompi-core/runtime-pi-extension").DefinedPiExtension<undefined>;
|
|
3
|
-
//#endregion
|
|
4
|
-
export { activateDoomPiEditExtension as default };
|
|
5
|
-
//# sourceMappingURL=pi.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pi.d.mts","names":[],"sources":["../../src/extensions/pi.ts"],"mappings":";qBAKa,mFAA2B"}
|
package/dist/extensions/pi.mjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{createHashlineEditTool as e}from"../tools/piEdit.mjs";import{PACKAGE_SOURCE as t}from"../constants/package.mjs";import{definePiExtension as n,definePiTool as r}from"@agimon-ai/doompi-core/pi-extension";const i=n(t,()=>({toolOverrides:[{source:t,tools:[`edit`],replacements:[r(e())]}]}));export{i as activateDoomPiEditExtension,i as default};
|
|
2
|
-
//# sourceMappingURL=pi.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pi.mjs","names":[],"sources":["../../src/extensions/pi.ts"],"sourcesContent":["import { definePiExtension, definePiTool } from '@agimon-ai/doompi-core/pi-extension';\n\nimport { PACKAGE_SOURCE } from '../constants/package';\nimport { createHashlineEditTool } from '../tools/piEdit';\n\nexport const activateDoomPiEditExtension = definePiExtension(PACKAGE_SOURCE, () => ({\n toolOverrides: [{ source: PACKAGE_SOURCE, tools: ['edit'], replacements: [definePiTool(createHashlineEditTool())] }],\n}));\nexport default activateDoomPiEditExtension;\n"],"mappings":"iNAKA,MAAa,EAA8B,EAAkB,OAAuB,CAClF,cAAe,CAAC,CAAE,OAAQ,EAAgB,MAAO,CAAC,MAAM,EAAG,aAAc,CAAC,EAAa,EAAuB,CAAC,CAAC,CAAE,CAAC,CACrH,EAAE"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("../tools/headlessEdit.cjs"),t=require("../constants/package.cjs"),n=(0,require("@agimon-ai/doompi-core/server-facet").defineServerPlugin)({name:t.PACKAGE_SOURCE,session:()=>({tools:[e.createHeadlessEditTool()]})});exports.default=n,exports.editServerFacet=n;
|
|
2
|
-
//# sourceMappingURL=server.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"server.cjs","names":["defineServerPlugin","PACKAGE_SOURCE","createHeadlessEditTool"],"sources":["../../src/extensions/server.ts"],"sourcesContent":["import { defineServerPlugin } from '@agimon-ai/doompi-core/server-facet';\n\nimport { PACKAGE_SOURCE } from '../constants/package';\nimport { createHeadlessEditTool } from '../tools/headlessEdit';\n\nexport const editServerFacet = defineServerPlugin({\n name: PACKAGE_SOURCE,\n session: () => ({ tools: [createHeadlessEditTool()] }),\n});\nexport default editServerFacet;\n"],"mappings":"kLAKa,GAAA,+CAAkBA,CAAAA,CAAAA,mBAAAA,CAAmB,CAChD,KAAMC,EAAAA,eACN,aAAgB,CAAE,MAAO,CAACC,EAAAA,uBAAuB,CAAC,CAAE,EACtD,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.cts","names":[],"sources":["../../src/extensions/server.ts"],"mappings":";qBAKa,+DAAe"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.mts","names":[],"sources":["../../src/extensions/server.ts"],"mappings":";qBAKa,+DAAe"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{createHeadlessEditTool as e}from"../tools/headlessEdit.mjs";import{PACKAGE_SOURCE as t}from"../constants/package.mjs";import{defineServerPlugin as n}from"@agimon-ai/doompi-core/server-facet";const r=n({name:t,session:()=>({tools:[e()]})});export{r as default,r as editServerFacet};
|
|
2
|
-
//# sourceMappingURL=server.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"server.mjs","names":[],"sources":["../../src/extensions/server.ts"],"sourcesContent":["import { defineServerPlugin } from '@agimon-ai/doompi-core/server-facet';\n\nimport { PACKAGE_SOURCE } from '../constants/package';\nimport { createHeadlessEditTool } from '../tools/headlessEdit';\n\nexport const editServerFacet = defineServerPlugin({\n name: PACKAGE_SOURCE,\n session: () => ({ tools: [createHeadlessEditTool()] }),\n});\nexport default editServerFacet;\n"],"mappings":"sMAKA,MAAa,EAAkB,EAAmB,CAChD,KAAM,EACN,aAAgB,CAAE,MAAO,CAAC,EAAuB,CAAC,CAAE,EACtD,CAAC"}
|
package/dist/index.cjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./schemas/editTool.cjs"),t=require("./services/editTool/index.cjs"),n=require("./tools/piEdit.cjs"),r=require("./tools/headlessEdit.cjs");exports.EditParamsSchema=e.EditParamsSchema,exports.HashlineRangeSchema=e.HashlineRangeSchema,exports.createHashlineEditTool=n.createHashlineEditTool,exports.createHeadlessEditTool=r.createHeadlessEditTool,exports.executeHashlineEdit=t.executeHashlineEdit;
|
package/dist/index.d.cts
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { EditParams, EditParamsSchema, HashlineRange, HashlineRangeSchema } from "./schemas/editTool.cjs";
|
|
2
|
-
import { executeHashlineEdit } from "./services/editTool/index.cjs";
|
|
3
|
-
import { createHashlineEditTool } from "./tools/piEdit.cjs";
|
|
4
|
-
import { createHeadlessEditTool } from "./tools/headlessEdit.cjs";
|
|
5
|
-
export { type EditParams, EditParamsSchema, type HashlineRange, HashlineRangeSchema, createHashlineEditTool, createHeadlessEditTool, executeHashlineEdit };
|
package/dist/index.d.mts
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { EditParams, EditParamsSchema, HashlineRange, HashlineRangeSchema } from "./schemas/editTool.mjs";
|
|
2
|
-
import { executeHashlineEdit } from "./services/editTool/index.mjs";
|
|
3
|
-
import { createHashlineEditTool } from "./tools/piEdit.mjs";
|
|
4
|
-
import { createHeadlessEditTool } from "./tools/headlessEdit.mjs";
|
|
5
|
-
export { type EditParams, EditParamsSchema, type HashlineRange, HashlineRangeSchema, createHashlineEditTool, createHeadlessEditTool, executeHashlineEdit };
|
package/dist/index.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{EditParamsSchema as e,HashlineRangeSchema as t}from"./schemas/editTool.mjs";import{executeHashlineEdit as n}from"./services/editTool/index.mjs";import{createHashlineEditTool as r}from"./tools/piEdit.mjs";import{createHeadlessEditTool as i}from"./tools/headlessEdit.mjs";export{e as EditParamsSchema,t as HashlineRangeSchema,r as createHashlineEditTool,i as createHeadlessEditTool,n as executeHashlineEdit};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"apiContracts.cjs","names":["defineApiContract"],"sources":["../../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract } from '@agimon-ai/doompi-core/api-contracts';\n\n/** This facet contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */\nexport const apiContracts = defineApiContract({ version: 1, http: [], sockets: [], dynamic: [] });\nexport default apiContracts;\n"],"mappings":"AAGA,MAAa,GAAA,gDAAeA,CAAAA,CAAAA,kBAAAA,CAAkB,CAAE,QAAS,EAAG,KAAM,CAAC,EAAG,QAAS,CAAC,EAAG,QAAS,CAAC,CAAE,CAAC"}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
//#region src/schemas/apiContracts.d.ts
|
|
2
|
-
/** This facet contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */
|
|
3
|
-
export declare const apiContracts: {
|
|
4
|
-
version: 1;
|
|
5
|
-
protocols?: Record<string, string> | undefined;
|
|
6
|
-
schemas?: Record<string, boolean | object> | undefined;
|
|
7
|
-
http: {
|
|
8
|
-
id: string;
|
|
9
|
-
scope: "global" | "session" | "workspace";
|
|
10
|
-
basePath?: string | undefined;
|
|
11
|
-
path: string;
|
|
12
|
-
method: "DELETE" | "GET" | "HEAD" | "OPTIONS" | "PATCH" | "POST" | "PUT";
|
|
13
|
-
description: string;
|
|
14
|
-
availability?: string | undefined;
|
|
15
|
-
authentication: "device" | "none" | "owner";
|
|
16
|
-
parameters?: {
|
|
17
|
-
name: string;
|
|
18
|
-
in: "header" | "path" | "query";
|
|
19
|
-
required: boolean;
|
|
20
|
-
schema: boolean | object;
|
|
21
|
-
}[] | undefined;
|
|
22
|
-
body?: {
|
|
23
|
-
contentType: string;
|
|
24
|
-
contentTypes?: string[] | undefined;
|
|
25
|
-
required: boolean;
|
|
26
|
-
schema: boolean | object;
|
|
27
|
-
} | undefined;
|
|
28
|
-
responses: Record<string, {
|
|
29
|
-
description: string;
|
|
30
|
-
contentType?: string | undefined;
|
|
31
|
-
schema?: boolean | object | undefined;
|
|
32
|
-
events?: Record<string, boolean | object> | undefined;
|
|
33
|
-
}>;
|
|
34
|
-
}[];
|
|
35
|
-
sockets: {
|
|
36
|
-
id: string;
|
|
37
|
-
scope: "global" | "session" | "workspace";
|
|
38
|
-
description: string;
|
|
39
|
-
availability?: string | undefined;
|
|
40
|
-
service: string;
|
|
41
|
-
member: string;
|
|
42
|
-
direction: "client-to-server" | "server-to-client";
|
|
43
|
-
kind: "channel" | "method" | "state";
|
|
44
|
-
input: boolean | object;
|
|
45
|
-
output?: boolean | object | undefined;
|
|
46
|
-
errors?: boolean | object | undefined;
|
|
47
|
-
}[];
|
|
48
|
-
dynamic: string[];
|
|
49
|
-
gaps?: string[] | undefined;
|
|
50
|
-
};
|
|
51
|
-
//#endregion
|
|
52
|
-
export { apiContracts as default };
|
|
53
|
-
//# sourceMappingURL=apiContracts.d.cts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"apiContracts.d.cts","names":[],"sources":["../../src/schemas/apiContracts.ts"],"mappings":";;qBAGa"}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
//#region src/schemas/apiContracts.d.ts
|
|
2
|
-
/** This facet contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */
|
|
3
|
-
export declare const apiContracts: {
|
|
4
|
-
version: 1;
|
|
5
|
-
protocols?: Record<string, string> | undefined;
|
|
6
|
-
schemas?: Record<string, boolean | object> | undefined;
|
|
7
|
-
http: {
|
|
8
|
-
id: string;
|
|
9
|
-
scope: "global" | "session" | "workspace";
|
|
10
|
-
basePath?: string | undefined;
|
|
11
|
-
path: string;
|
|
12
|
-
method: "DELETE" | "GET" | "HEAD" | "OPTIONS" | "PATCH" | "POST" | "PUT";
|
|
13
|
-
description: string;
|
|
14
|
-
availability?: string | undefined;
|
|
15
|
-
authentication: "device" | "none" | "owner";
|
|
16
|
-
parameters?: {
|
|
17
|
-
name: string;
|
|
18
|
-
in: "header" | "path" | "query";
|
|
19
|
-
required: boolean;
|
|
20
|
-
schema: boolean | object;
|
|
21
|
-
}[] | undefined;
|
|
22
|
-
body?: {
|
|
23
|
-
contentType: string;
|
|
24
|
-
contentTypes?: string[] | undefined;
|
|
25
|
-
required: boolean;
|
|
26
|
-
schema: boolean | object;
|
|
27
|
-
} | undefined;
|
|
28
|
-
responses: Record<string, {
|
|
29
|
-
description: string;
|
|
30
|
-
contentType?: string | undefined;
|
|
31
|
-
schema?: boolean | object | undefined;
|
|
32
|
-
events?: Record<string, boolean | object> | undefined;
|
|
33
|
-
}>;
|
|
34
|
-
}[];
|
|
35
|
-
sockets: {
|
|
36
|
-
id: string;
|
|
37
|
-
scope: "global" | "session" | "workspace";
|
|
38
|
-
description: string;
|
|
39
|
-
availability?: string | undefined;
|
|
40
|
-
service: string;
|
|
41
|
-
member: string;
|
|
42
|
-
direction: "client-to-server" | "server-to-client";
|
|
43
|
-
kind: "channel" | "method" | "state";
|
|
44
|
-
input: boolean | object;
|
|
45
|
-
output?: boolean | object | undefined;
|
|
46
|
-
errors?: boolean | object | undefined;
|
|
47
|
-
}[];
|
|
48
|
-
dynamic: string[];
|
|
49
|
-
gaps?: string[] | undefined;
|
|
50
|
-
};
|
|
51
|
-
//#endregion
|
|
52
|
-
export { apiContracts as default };
|
|
53
|
-
//# sourceMappingURL=apiContracts.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"apiContracts.d.mts","names":[],"sources":["../../src/schemas/apiContracts.ts"],"mappings":";;qBAGa"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"apiContracts.mjs","names":[],"sources":["../../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract } from '@agimon-ai/doompi-core/api-contracts';\n\n/** This facet contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */\nexport const apiContracts = defineApiContract({ version: 1, http: [], sockets: [], dynamic: [] });\nexport default apiContracts;\n"],"mappings":"yEAGA,MAAa,EAAe,EAAkB,CAAE,QAAS,EAAG,KAAM,CAAC,EAAG,QAAS,CAAC,EAAG,QAAS,CAAC,CAAE,CAAC"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
let e=require("typebox");const t=e.Type.Object({from:e.Type.String({description:`One inclusive starting anchor, for example 5#abc. Do not paste multiple lines.`}),to:e.Type.String({description:`One inclusive ending anchor, for example 8#def. Do not paste multiple lines.`}),content:e.Type.Optional(e.Type.Union([e.Type.String({description:`Replacement content. Empty content deletes the selected lines.`}),e.Type.Null({description:`Delete the selected lines.`})]))}),n=e.Type.Object({path:e.Type.String({description:`Path to the file returned by a compatible hashline read or grep tool.`}),hash:e.Type.String({description:`Eight-character exact-byte file tag returned by read or grep.`}),edits:e.Type.Array(t,{minItems:1,description:`Non-overlapping inclusive ranges from the same original snapshot.`})});exports.EditParamsSchema=n,exports.HashlineRangeSchema=t;
|
|
2
|
-
//# sourceMappingURL=editTool.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"editTool.cjs","names":["Type"],"sources":["../../src/schemas/editTool.ts"],"sourcesContent":["import { type Static, Type } from 'typebox';\n\nexport const HashlineRangeSchema = Type.Object({\n from: Type.String({ description: 'One inclusive starting anchor, for example 5#abc. Do not paste multiple lines.' }),\n to: Type.String({ description: 'One inclusive ending anchor, for example 8#def. Do not paste multiple lines.' }),\n content: Type.Optional(\n Type.Union([\n Type.String({ description: 'Replacement content. Empty content deletes the selected lines.' }),\n Type.Null({ description: 'Delete the selected lines.' }),\n ]),\n ),\n});\n\nexport const EditParamsSchema = Type.Object({\n path: Type.String({ description: 'Path to the file returned by a compatible hashline read or grep tool.' }),\n hash: Type.String({ description: 'Eight-character exact-byte file tag returned by read or grep.' }),\n edits: Type.Array(HashlineRangeSchema, {\n minItems: 1,\n description: 'Non-overlapping inclusive ranges from the same original snapshot.',\n }),\n});\n\nexport type HashlineRange = Static<typeof HashlineRangeSchema>;\nexport type EditParams = Static<typeof EditParamsSchema>;\n"],"mappings":"yBAEA,MAAa,EAAsBA,EAAAA,KAAK,OAAO,CAC7C,KAAMA,EAAAA,KAAK,OAAO,CAAE,YAAa,gFAAiF,CAAC,EACnH,GAAIA,EAAAA,KAAK,OAAO,CAAE,YAAa,8EAA+E,CAAC,EAC/G,QAASA,EAAAA,KAAK,SACZA,EAAAA,KAAK,MAAM,CACTA,EAAAA,KAAK,OAAO,CAAE,YAAa,gEAAiE,CAAC,EAC7FA,EAAAA,KAAK,KAAK,CAAE,YAAa,4BAA6B,CAAC,CACzD,CAAC,CACH,CACF,CAAC,EAEY,EAAmBA,EAAAA,KAAK,OAAO,CAC1C,KAAMA,EAAAA,KAAK,OAAO,CAAE,YAAa,uEAAwE,CAAC,EAC1G,KAAMA,EAAAA,KAAK,OAAO,CAAE,YAAa,+DAAgE,CAAC,EAClG,MAAOA,EAAAA,KAAK,MAAM,EAAqB,CACrC,SAAU,EACV,YAAa,mEACf,CAAC,CACH,CAAC"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { Static, Type } from "typebox";
|
|
2
|
-
//#region src/schemas/editTool.d.ts
|
|
3
|
-
export declare const HashlineRangeSchema: Type.TObject<{
|
|
4
|
-
from: Type.TString;
|
|
5
|
-
to: Type.TString;
|
|
6
|
-
content: Type.TOptional<Type.TUnion<[Type.TString, Type.TNull]>>;
|
|
7
|
-
}>;
|
|
8
|
-
export declare const EditParamsSchema: Type.TObject<{
|
|
9
|
-
path: Type.TString;
|
|
10
|
-
hash: Type.TString;
|
|
11
|
-
edits: Type.TArray<Type.TObject<{
|
|
12
|
-
from: Type.TString;
|
|
13
|
-
to: Type.TString;
|
|
14
|
-
content: Type.TOptional<Type.TUnion<[Type.TString, Type.TNull]>>;
|
|
15
|
-
}>>;
|
|
16
|
-
}>;
|
|
17
|
-
export type HashlineRange = Static<typeof HashlineRangeSchema>;
|
|
18
|
-
export type EditParams = Static<typeof EditParamsSchema>;
|
|
19
|
-
//#endregion
|
|
20
|
-
//# sourceMappingURL=editTool.d.cts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"editTool.d.cts","names":[],"sources":["../../src/schemas/editTool.ts"],"mappings":";;qBAEa,qBAAmB,KAAA;;;;;qBAWnB,kBAAgB,KAAA;;;;;;;;;YASjB,gBAAgB,cAAc;YAC9B,aAAa,cAAc"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { Static, Type } from "typebox";
|
|
2
|
-
//#region src/schemas/editTool.d.ts
|
|
3
|
-
export declare const HashlineRangeSchema: Type.TObject<{
|
|
4
|
-
from: Type.TString;
|
|
5
|
-
to: Type.TString;
|
|
6
|
-
content: Type.TOptional<Type.TUnion<[Type.TString, Type.TNull]>>;
|
|
7
|
-
}>;
|
|
8
|
-
export declare const EditParamsSchema: Type.TObject<{
|
|
9
|
-
path: Type.TString;
|
|
10
|
-
hash: Type.TString;
|
|
11
|
-
edits: Type.TArray<Type.TObject<{
|
|
12
|
-
from: Type.TString;
|
|
13
|
-
to: Type.TString;
|
|
14
|
-
content: Type.TOptional<Type.TUnion<[Type.TString, Type.TNull]>>;
|
|
15
|
-
}>>;
|
|
16
|
-
}>;
|
|
17
|
-
export type HashlineRange = Static<typeof HashlineRangeSchema>;
|
|
18
|
-
export type EditParams = Static<typeof EditParamsSchema>;
|
|
19
|
-
//#endregion
|
|
20
|
-
//# sourceMappingURL=editTool.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"editTool.d.mts","names":[],"sources":["../../src/schemas/editTool.ts"],"mappings":";;qBAEa,qBAAmB,KAAA;;;;;qBAWnB,kBAAgB,KAAA;;;;;;;;;YASjB,gBAAgB,cAAc;YAC9B,aAAa,cAAc"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{Type as e}from"typebox";const t=e.Object({from:e.String({description:`One inclusive starting anchor, for example 5#abc. Do not paste multiple lines.`}),to:e.String({description:`One inclusive ending anchor, for example 8#def. Do not paste multiple lines.`}),content:e.Optional(e.Union([e.String({description:`Replacement content. Empty content deletes the selected lines.`}),e.Null({description:`Delete the selected lines.`})]))}),n=e.Object({path:e.String({description:`Path to the file returned by a compatible hashline read or grep tool.`}),hash:e.String({description:`Eight-character exact-byte file tag returned by read or grep.`}),edits:e.Array(t,{minItems:1,description:`Non-overlapping inclusive ranges from the same original snapshot.`})});export{n as EditParamsSchema,t as HashlineRangeSchema};
|
|
2
|
-
//# sourceMappingURL=editTool.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"editTool.mjs","names":[],"sources":["../../src/schemas/editTool.ts"],"sourcesContent":["import { type Static, Type } from 'typebox';\n\nexport const HashlineRangeSchema = Type.Object({\n from: Type.String({ description: 'One inclusive starting anchor, for example 5#abc. Do not paste multiple lines.' }),\n to: Type.String({ description: 'One inclusive ending anchor, for example 8#def. Do not paste multiple lines.' }),\n content: Type.Optional(\n Type.Union([\n Type.String({ description: 'Replacement content. Empty content deletes the selected lines.' }),\n Type.Null({ description: 'Delete the selected lines.' }),\n ]),\n ),\n});\n\nexport const EditParamsSchema = Type.Object({\n path: Type.String({ description: 'Path to the file returned by a compatible hashline read or grep tool.' }),\n hash: Type.String({ description: 'Eight-character exact-byte file tag returned by read or grep.' }),\n edits: Type.Array(HashlineRangeSchema, {\n minItems: 1,\n description: 'Non-overlapping inclusive ranges from the same original snapshot.',\n }),\n});\n\nexport type HashlineRange = Static<typeof HashlineRangeSchema>;\nexport type EditParams = Static<typeof EditParamsSchema>;\n"],"mappings":"+BAEA,MAAa,EAAsB,EAAK,OAAO,CAC7C,KAAM,EAAK,OAAO,CAAE,YAAa,gFAAiF,CAAC,EACnH,GAAI,EAAK,OAAO,CAAE,YAAa,8EAA+E,CAAC,EAC/G,QAAS,EAAK,SACZ,EAAK,MAAM,CACT,EAAK,OAAO,CAAE,YAAa,gEAAiE,CAAC,EAC7F,EAAK,KAAK,CAAE,YAAa,4BAA6B,CAAC,CACzD,CAAC,CACH,CACF,CAAC,EAEY,EAAmB,EAAK,OAAO,CAC1C,KAAM,EAAK,OAAO,CAAE,YAAa,uEAAwE,CAAC,EAC1G,KAAM,EAAK,OAAO,CAAE,YAAa,+DAAgE,CAAC,EAClG,MAAO,EAAK,MAAM,EAAqB,CACrC,SAAU,EACV,YAAa,mEACf,CAAC,CACH,CAAC"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
let e=require("node:fs"),t=require("node:fs/promises"),n=require("@agimon-ai/doompi-hashline"),r=require("@agimon-ai/doompi-hashline/files"),i=require("@earendil-works/pi-coding-agent");function a(e){if(e?.aborted)throw Error(`Operation aborted`)}async function o(o,c,l){let u=(0,r.resolveInputPath)(o.path,c),d=(0,n.normalizeFileTag)(o.hash);return(0,i.withFileMutationQueue)(u,async()=>{a(l),await(0,t.access)(u,e.constants.R_OK|e.constants.W_OK);let f=await(0,t.readFile)(u);a(l);let p=(0,r.computeFileTag)(f);if(p!==d)throw Error(`Stale file hash ${d}. Current hash is ${p}. Re-read the file and retry.`);let m=f.subarray(0,3).equals(Buffer.from([239,187,191])),h=(0,r.decodeUtf8)(f,o.path),g=(0,n.stripBom)(h),_=(0,n.normalizeToLf)(g),v=(0,n.applyHashlineEdits)(_,o.edits),y=s(g,v.edits);if((0,n.normalizeToLf)(y)!==v.content)throw Error(`Could not preserve the file line endings safely. The file was not changed.`);let b=(0,i.generateDiffString)(_,v.content),x=(0,i.generateUnifiedPatch)((0,r.displayPath)(u,c),_,v.content),S={diff:b.diff,patch:x,firstChangedLine:b.firstChangedLine};if(a(l),!(await(0,t.readFile)(u)).equals(f))throw Error(`The file changed while the edit was being prepared. Re-read it and retry.`);if(a(l),v.content!==_){let e=Buffer.from(`${m?``:``}${y}`,`utf8`);await(0,t.writeFile)(u,e)}let C=v.edits.length,w=C===1?`range`:`ranges`;return{content:[{type:`text`,text:`${v.content===_?`No changes needed in ${o.path}.`:`Edited ${o.path} (${C} ${w}).`} Re-read before editing it again.`}],details:S}})}function s(e,t){let n=c(e),r=n.find(e=>e.ending!==``)?.ending??`
|
|
2
|
-
`;for(let e of[...t].reverse()){let t=e.from.line-1,i=e.to.line-e.from.line+1,a=n.slice(t,t+i),o=a.at(-1)?.ending??``,s=a.find(e=>e.ending!==``)?.ending??r,c=l(e.content);if(c.length===0&&a.at(-1)?.ending===``&&t>0){let e=n[t-1];e&&(n[t-1]={...e,ending:``})}let u=c.map((e,t)=>({text:e,ending:t===c.length-1?o:s}));n.splice(t,i,...u)}return n.map(e=>`${e.text}${e.ending}`).join(``)}function c(e){let t=[],n=0;for(let r=0;r<e.length;r+=1){let i=e[r];if(i!==`\r`&&i!==`
|
|
3
|
-
`)continue;let a=i===`\r`&&e[r+1]===`
|
|
4
|
-
`?`\r
|
|
5
|
-
`:i;t.push({text:e.slice(n,r),ending:a}),a===`\r
|
|
6
|
-
`&&(r+=1),n=r+1}return t.push({text:e.slice(n),ending:``}),t}function l(e){if(e===null||e===``)return[];let t=(0,n.normalizeToLf)(e),r=t.endsWith(`
|
|
7
|
-
`)?t.slice(0,-1):t;return r===``?[]:r.split(`
|
|
8
|
-
`)}exports.assertNotAborted=a,exports.executeHashlineEdit=o;
|
|
9
|
-
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["resolveInputPath","normalizeFileTag","withFileMutationQueue","access","constants","readFile","computeFileTag","decodeUtf8","stripBom","normalizeToLf","applyHashlineEdits","generateDiffString","generateUnifiedPatch","displayPath","writeFile"],"sources":["../../../src/services/editTool/index.ts"],"sourcesContent":["import { constants } from 'node:fs';\nimport { access, readFile, writeFile } from 'node:fs/promises';\n\nimport {\n applyHashlineEdits,\n normalizeFileTag,\n normalizeToLf,\n stripBom,\n type PreparedHashlineEdit,\n} from '@agimon-ai/doompi-hashline';\nimport { computeFileTag, decodeUtf8, displayPath, resolveInputPath } from '@agimon-ai/doompi-hashline/files';\nimport {\n generateDiffString,\n generateUnifiedPatch,\n withFileMutationQueue,\n type EditToolDetails,\n} from '@earendil-works/pi-coding-agent';\n\nimport type { EditParams } from '../../schemas/editTool';\n\nexport function assertNotAborted(signal: AbortSignal | undefined): void {\n if (signal?.aborted) throw new Error('Operation aborted');\n}\n\nexport async function executeHashlineEdit(\n params: EditParams,\n cwd: string,\n signal: AbortSignal | undefined,\n): Promise<{ content: [{ type: 'text'; text: string }]; details: EditToolDetails }> {\n const absolutePath = resolveInputPath(params.path, cwd);\n const expectedHash = normalizeFileTag(params.hash);\n return withFileMutationQueue(absolutePath, async () => {\n assertNotAborted(signal);\n await access(absolutePath, constants.R_OK | constants.W_OK);\n const beforeBytes = await readFile(absolutePath);\n assertNotAborted(signal);\n\n const actualHash = computeFileTag(beforeBytes);\n if (actualHash !== expectedHash) {\n throw new Error(`Stale file hash ${expectedHash}. Current hash is ${actualHash}. Re-read the file and retry.`);\n }\n\n const hasBom = beforeBytes.subarray(0, 3).equals(Buffer.from([0xef, 0xbb, 0xbf]));\n const decoded = decodeUtf8(beforeBytes, params.path);\n const withoutBom = stripBom(decoded);\n const before = normalizeToLf(withoutBom);\n const applied = applyHashlineEdits(before, params.edits);\n const editedText = restoreOriginalLineEndings(withoutBom, applied.edits);\n if (normalizeToLf(editedText) !== applied.content) {\n throw new Error('Could not preserve the file line endings safely. The file was not changed.');\n }\n const diff = generateDiffString(before, applied.content);\n const patch = generateUnifiedPatch(displayPath(absolutePath, cwd), before, applied.content);\n const details: EditToolDetails = { diff: diff.diff, patch, firstChangedLine: diff.firstChangedLine };\n\n assertNotAborted(signal);\n const currentBytes = await readFile(absolutePath);\n if (!currentBytes.equals(beforeBytes)) {\n throw new Error('The file changed while the edit was being prepared. Re-read it and retry.');\n }\n assertNotAborted(signal);\n\n if (applied.content !== before) {\n const output = Buffer.from(`${hasBom ? '\\ufeff' : ''}${editedText}`, 'utf8');\n await writeFile(absolutePath, output);\n }\n\n const count = applied.edits.length;\n const noun = count === 1 ? 'range' : 'ranges';\n const message =\n applied.content === before ? `No changes needed in ${params.path}.` : `Edited ${params.path} (${count} ${noun}).`;\n return { content: [{ type: 'text', text: `${message} Re-read before editing it again.` }], details };\n });\n}\n\ninterface LineToken {\n readonly text: string;\n readonly ending: '\\r\\n' | '\\n' | '\\r' | '';\n}\n\nfunction restoreOriginalLineEndings(original: string, edits: readonly PreparedHashlineEdit[]): string {\n const tokens = tokenizeLines(original);\n const defaultEnding = tokens.find((token) => token.ending !== '')?.ending ?? '\\n';\n for (const edit of [...edits].reverse()) {\n const start = edit.from.line - 1;\n const count = edit.to.line - edit.from.line + 1;\n const removed = tokens.slice(start, start + count);\n const inheritedEnding = removed.at(-1)?.ending ?? '';\n const internalEnding = removed.find((token) => token.ending !== '')?.ending ?? defaultEnding;\n const lines = replacementLines(edit.content);\n if (lines.length === 0 && removed.at(-1)?.ending === '' && start > 0) {\n const previous = tokens[start - 1];\n if (previous) tokens[start - 1] = { ...previous, ending: '' };\n }\n const replacements = lines.map<LineToken>((text, index) => ({\n text,\n ending: index === lines.length - 1 ? inheritedEnding : internalEnding,\n }));\n tokens.splice(start, count, ...replacements);\n }\n return tokens.map((token) => `${token.text}${token.ending}`).join('');\n}\n\nfunction tokenizeLines(content: string): LineToken[] {\n const tokens: LineToken[] = [];\n let start = 0;\n for (let index = 0; index < content.length; index += 1) {\n const character = content[index];\n if (character !== '\\r' && character !== '\\n') continue;\n const ending = character === '\\r' && content[index + 1] === '\\n' ? '\\r\\n' : character;\n tokens.push({ text: content.slice(start, index), ending });\n if (ending === '\\r\\n') index += 1;\n start = index + 1;\n }\n tokens.push({ text: content.slice(start), ending: '' });\n return tokens;\n}\n\nfunction replacementLines(content: string | null): string[] {\n if (content === null || content === '') return [];\n const normalized = normalizeToLf(content);\n const trimmed = normalized.endsWith('\\n') ? normalized.slice(0, -1) : normalized;\n return trimmed === '' ? [] : trimmed.split('\\n');\n}\n"],"mappings":"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"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { EditParams } from "../../schemas/editTool.cjs";
|
|
2
|
-
import { EditToolDetails } from "@earendil-works/pi-coding-agent";
|
|
3
|
-
//#region src/services/editTool/index.d.ts
|
|
4
|
-
export declare function executeHashlineEdit(params: EditParams, cwd: string, signal: AbortSignal | undefined): Promise<{
|
|
5
|
-
content: [{
|
|
6
|
-
type: 'text';
|
|
7
|
-
text: string;
|
|
8
|
-
}];
|
|
9
|
-
details: EditToolDetails;
|
|
10
|
-
}>;
|
|
11
|
-
//#endregion
|
|
12
|
-
//# sourceMappingURL=index.d.cts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../../../src/services/editTool/index.ts"],"mappings":";;;wBAwBsB,oBACpB,QAAQ,YACR,aACA,QAAQ,0BACP;EAAU;IAAY;IAAc;;EAAiB,SAAS"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { EditParams } from "../../schemas/editTool.mjs";
|
|
2
|
-
import { EditToolDetails } from "@earendil-works/pi-coding-agent";
|
|
3
|
-
//#region src/services/editTool/index.d.ts
|
|
4
|
-
export declare function executeHashlineEdit(params: EditParams, cwd: string, signal: AbortSignal | undefined): Promise<{
|
|
5
|
-
content: [{
|
|
6
|
-
type: 'text';
|
|
7
|
-
text: string;
|
|
8
|
-
}];
|
|
9
|
-
details: EditToolDetails;
|
|
10
|
-
}>;
|
|
11
|
-
//#endregion
|
|
12
|
-
//# sourceMappingURL=index.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../../src/services/editTool/index.ts"],"mappings":";;;wBAwBsB,oBACpB,QAAQ,YACR,aACA,QAAQ,0BACP;EAAU;IAAY;IAAc;;EAAiB,SAAS"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import{constants as e}from"node:fs";import{access as t,readFile as n,writeFile as r}from"node:fs/promises";import{applyHashlineEdits as i,normalizeFileTag as a,normalizeToLf as o,stripBom as s}from"@agimon-ai/doompi-hashline";import{computeFileTag as c,decodeUtf8 as l,displayPath as u,resolveInputPath as d}from"@agimon-ai/doompi-hashline/files";import{generateDiffString as f,generateUnifiedPatch as p,withFileMutationQueue as m}from"@earendil-works/pi-coding-agent";function h(e){if(e?.aborted)throw Error(`Operation aborted`)}async function g(g,v,y){let b=d(g.path,v),x=a(g.hash);return m(b,async()=>{h(y),await t(b,e.R_OK|e.W_OK);let a=await n(b);h(y);let d=c(a);if(d!==x)throw Error(`Stale file hash ${x}. Current hash is ${d}. Re-read the file and retry.`);let m=a.subarray(0,3).equals(Buffer.from([239,187,191])),S=l(a,g.path),C=s(S),w=o(C),T=i(w,g.edits),E=_(C,T.edits);if(o(E)!==T.content)throw Error(`Could not preserve the file line endings safely. The file was not changed.`);let D=f(w,T.content),O=p(u(b,v),w,T.content),k={diff:D.diff,patch:O,firstChangedLine:D.firstChangedLine};if(h(y),!(await n(b)).equals(a))throw Error(`The file changed while the edit was being prepared. Re-read it and retry.`);if(h(y),T.content!==w){let e=Buffer.from(`${m?``:``}${E}`,`utf8`);await r(b,e)}let A=T.edits.length,j=A===1?`range`:`ranges`;return{content:[{type:`text`,text:`${T.content===w?`No changes needed in ${g.path}.`:`Edited ${g.path} (${A} ${j}).`} Re-read before editing it again.`}],details:k}})}function _(e,t){let n=v(e),r=n.find(e=>e.ending!==``)?.ending??`
|
|
2
|
-
`;for(let e of[...t].reverse()){let t=e.from.line-1,i=e.to.line-e.from.line+1,a=n.slice(t,t+i),o=a.at(-1)?.ending??``,s=a.find(e=>e.ending!==``)?.ending??r,c=y(e.content);if(c.length===0&&a.at(-1)?.ending===``&&t>0){let e=n[t-1];e&&(n[t-1]={...e,ending:``})}let l=c.map((e,t)=>({text:e,ending:t===c.length-1?o:s}));n.splice(t,i,...l)}return n.map(e=>`${e.text}${e.ending}`).join(``)}function v(e){let t=[],n=0;for(let r=0;r<e.length;r+=1){let i=e[r];if(i!==`\r`&&i!==`
|
|
3
|
-
`)continue;let a=i===`\r`&&e[r+1]===`
|
|
4
|
-
`?`\r
|
|
5
|
-
`:i;t.push({text:e.slice(n,r),ending:a}),a===`\r
|
|
6
|
-
`&&(r+=1),n=r+1}return t.push({text:e.slice(n),ending:``}),t}function y(e){if(e===null||e===``)return[];let t=o(e),n=t.endsWith(`
|
|
7
|
-
`)?t.slice(0,-1):t;return n===``?[]:n.split(`
|
|
8
|
-
`)}export{h as assertNotAborted,g as executeHashlineEdit};
|
|
9
|
-
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/services/editTool/index.ts"],"sourcesContent":["import { constants } from 'node:fs';\nimport { access, readFile, writeFile } from 'node:fs/promises';\n\nimport {\n applyHashlineEdits,\n normalizeFileTag,\n normalizeToLf,\n stripBom,\n type PreparedHashlineEdit,\n} from '@agimon-ai/doompi-hashline';\nimport { computeFileTag, decodeUtf8, displayPath, resolveInputPath } from '@agimon-ai/doompi-hashline/files';\nimport {\n generateDiffString,\n generateUnifiedPatch,\n withFileMutationQueue,\n type EditToolDetails,\n} from '@earendil-works/pi-coding-agent';\n\nimport type { EditParams } from '../../schemas/editTool';\n\nexport function assertNotAborted(signal: AbortSignal | undefined): void {\n if (signal?.aborted) throw new Error('Operation aborted');\n}\n\nexport async function executeHashlineEdit(\n params: EditParams,\n cwd: string,\n signal: AbortSignal | undefined,\n): Promise<{ content: [{ type: 'text'; text: string }]; details: EditToolDetails }> {\n const absolutePath = resolveInputPath(params.path, cwd);\n const expectedHash = normalizeFileTag(params.hash);\n return withFileMutationQueue(absolutePath, async () => {\n assertNotAborted(signal);\n await access(absolutePath, constants.R_OK | constants.W_OK);\n const beforeBytes = await readFile(absolutePath);\n assertNotAborted(signal);\n\n const actualHash = computeFileTag(beforeBytes);\n if (actualHash !== expectedHash) {\n throw new Error(`Stale file hash ${expectedHash}. Current hash is ${actualHash}. Re-read the file and retry.`);\n }\n\n const hasBom = beforeBytes.subarray(0, 3).equals(Buffer.from([0xef, 0xbb, 0xbf]));\n const decoded = decodeUtf8(beforeBytes, params.path);\n const withoutBom = stripBom(decoded);\n const before = normalizeToLf(withoutBom);\n const applied = applyHashlineEdits(before, params.edits);\n const editedText = restoreOriginalLineEndings(withoutBom, applied.edits);\n if (normalizeToLf(editedText) !== applied.content) {\n throw new Error('Could not preserve the file line endings safely. The file was not changed.');\n }\n const diff = generateDiffString(before, applied.content);\n const patch = generateUnifiedPatch(displayPath(absolutePath, cwd), before, applied.content);\n const details: EditToolDetails = { diff: diff.diff, patch, firstChangedLine: diff.firstChangedLine };\n\n assertNotAborted(signal);\n const currentBytes = await readFile(absolutePath);\n if (!currentBytes.equals(beforeBytes)) {\n throw new Error('The file changed while the edit was being prepared. Re-read it and retry.');\n }\n assertNotAborted(signal);\n\n if (applied.content !== before) {\n const output = Buffer.from(`${hasBom ? '\\ufeff' : ''}${editedText}`, 'utf8');\n await writeFile(absolutePath, output);\n }\n\n const count = applied.edits.length;\n const noun = count === 1 ? 'range' : 'ranges';\n const message =\n applied.content === before ? `No changes needed in ${params.path}.` : `Edited ${params.path} (${count} ${noun}).`;\n return { content: [{ type: 'text', text: `${message} Re-read before editing it again.` }], details };\n });\n}\n\ninterface LineToken {\n readonly text: string;\n readonly ending: '\\r\\n' | '\\n' | '\\r' | '';\n}\n\nfunction restoreOriginalLineEndings(original: string, edits: readonly PreparedHashlineEdit[]): string {\n const tokens = tokenizeLines(original);\n const defaultEnding = tokens.find((token) => token.ending !== '')?.ending ?? '\\n';\n for (const edit of [...edits].reverse()) {\n const start = edit.from.line - 1;\n const count = edit.to.line - edit.from.line + 1;\n const removed = tokens.slice(start, start + count);\n const inheritedEnding = removed.at(-1)?.ending ?? '';\n const internalEnding = removed.find((token) => token.ending !== '')?.ending ?? defaultEnding;\n const lines = replacementLines(edit.content);\n if (lines.length === 0 && removed.at(-1)?.ending === '' && start > 0) {\n const previous = tokens[start - 1];\n if (previous) tokens[start - 1] = { ...previous, ending: '' };\n }\n const replacements = lines.map<LineToken>((text, index) => ({\n text,\n ending: index === lines.length - 1 ? inheritedEnding : internalEnding,\n }));\n tokens.splice(start, count, ...replacements);\n }\n return tokens.map((token) => `${token.text}${token.ending}`).join('');\n}\n\nfunction tokenizeLines(content: string): LineToken[] {\n const tokens: LineToken[] = [];\n let start = 0;\n for (let index = 0; index < content.length; index += 1) {\n const character = content[index];\n if (character !== '\\r' && character !== '\\n') continue;\n const ending = character === '\\r' && content[index + 1] === '\\n' ? '\\r\\n' : character;\n tokens.push({ text: content.slice(start, index), ending });\n if (ending === '\\r\\n') index += 1;\n start = index + 1;\n }\n tokens.push({ text: content.slice(start), ending: '' });\n return tokens;\n}\n\nfunction replacementLines(content: string | null): string[] {\n if (content === null || content === '') return [];\n const normalized = normalizeToLf(content);\n const trimmed = normalized.endsWith('\\n') ? normalized.slice(0, -1) : normalized;\n return trimmed === '' ? [] : trimmed.split('\\n');\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const e=require("../schemas/editTool.cjs"),t=require("../services/editTool/index.cjs");function n(){return{name:`edit`,label:`edit`,description:`Edit one file using its exact snapshot hash and inclusive anchors such as 5#abc from read or grep. Each from and to value must contain one anchor, not a pasted block. All ranges refer to the original snapshot. Empty or omitted content deletes a range.`,promptSnippet:`Edit files with snapshot-bound hashline ranges`,promptGuidelines:[`Copy path, hash, and anchors from the latest compatible read or grep result. Re-read after every successful edit.`,`Pass one anchor such as 5#abc in each from and to value. Do not paste tagged lines or multiline blocks.`],parameters:e.EditParamsSchema,executionMode:`parallel`,execute:(e,n,r,i,a)=>t.executeHashlineEdit(n,a.cwd,r)}}exports.createHeadlessEditTool=n;
|
|
2
|
-
//# sourceMappingURL=headlessEdit.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"headlessEdit.cjs","names":["EditParamsSchema","executeHashlineEdit"],"sources":["../../src/tools/headlessEdit.ts"],"sourcesContent":["import type {\n DoomHeadlessExecutionContext,\n DoomHeadlessTool,\n DoomHeadlessToolResult,\n} from '@agimon-ai/doompi-core/headless';\n\nimport { EditParamsSchema, type EditParams } from '../schemas/editTool';\nimport { executeHashlineEdit } from '../services/editTool';\n\nexport function createHeadlessEditTool(): DoomHeadlessTool<typeof EditParamsSchema> {\n return {\n name: 'edit',\n label: 'edit',\n description:\n 'Edit one file using its exact snapshot hash and inclusive anchors such as 5#abc from read or grep. Each from and to value must contain one anchor, not a pasted block. All ranges refer to the original snapshot. Empty or omitted content deletes a range.',\n promptSnippet: 'Edit files with snapshot-bound hashline ranges',\n promptGuidelines: [\n 'Copy path, hash, and anchors from the latest compatible read or grep result. Re-read after every successful edit.',\n 'Pass one anchor such as 5#abc in each from and to value. Do not paste tagged lines or multiline blocks.',\n ],\n parameters: EditParamsSchema,\n executionMode: 'parallel',\n execute: (\n _toolCallId: string,\n params: EditParams,\n signal: AbortSignal | undefined,\n _onUpdate: ((result: DoomHeadlessToolResult) => void) | undefined,\n context: DoomHeadlessExecutionContext,\n ) => executeHashlineEdit(params, context.cwd, signal),\n };\n}\n"],"mappings":"uFASA,SAAgB,GAAoE,CAClF,MAAO,CACL,KAAM,OACN,MAAO,OACP,YACE,8PACF,cAAe,iDACf,iBAAkB,CAChB,oHACA,yGACF,EACA,WAAYA,EAAAA,iBACZ,cAAe,WACf,SACE,EACA,EACA,EACA,EACA,IACGC,EAAAA,oBAAoB,EAAQ,EAAQ,IAAK,CAAM,CACtD,CACF"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { EditParamsSchema } from "../schemas/editTool.cjs";
|
|
2
|
-
import { DoomHeadlessTool } from "@agimon-ai/doompi-core/headless";
|
|
3
|
-
//#region src/tools/headlessEdit.d.ts
|
|
4
|
-
export declare function createHeadlessEditTool(): DoomHeadlessTool<typeof EditParamsSchema>;
|
|
5
|
-
//#endregion
|
|
6
|
-
//# sourceMappingURL=headlessEdit.d.cts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"headlessEdit.d.cts","names":[],"sources":["../../src/tools/headlessEdit.ts"],"mappings":";;;wBASgB,0BAA0B,wBAAwB"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { EditParamsSchema } from "../schemas/editTool.mjs";
|
|
2
|
-
import { DoomHeadlessTool } from "@agimon-ai/doompi-core/headless";
|
|
3
|
-
//#region src/tools/headlessEdit.d.ts
|
|
4
|
-
export declare function createHeadlessEditTool(): DoomHeadlessTool<typeof EditParamsSchema>;
|
|
5
|
-
//#endregion
|
|
6
|
-
//# sourceMappingURL=headlessEdit.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"headlessEdit.d.mts","names":[],"sources":["../../src/tools/headlessEdit.ts"],"mappings":";;;wBASgB,0BAA0B,wBAAwB"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{EditParamsSchema as e}from"../schemas/editTool.mjs";import{executeHashlineEdit as t}from"../services/editTool/index.mjs";function n(){return{name:`edit`,label:`edit`,description:`Edit one file using its exact snapshot hash and inclusive anchors such as 5#abc from read or grep. Each from and to value must contain one anchor, not a pasted block. All ranges refer to the original snapshot. Empty or omitted content deletes a range.`,promptSnippet:`Edit files with snapshot-bound hashline ranges`,promptGuidelines:[`Copy path, hash, and anchors from the latest compatible read or grep result. Re-read after every successful edit.`,`Pass one anchor such as 5#abc in each from and to value. Do not paste tagged lines or multiline blocks.`],parameters:e,executionMode:`parallel`,execute:(e,n,r,i,a)=>t(n,a.cwd,r)}}export{n as createHeadlessEditTool};
|
|
2
|
-
//# sourceMappingURL=headlessEdit.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"headlessEdit.mjs","names":[],"sources":["../../src/tools/headlessEdit.ts"],"sourcesContent":["import type {\n DoomHeadlessExecutionContext,\n DoomHeadlessTool,\n DoomHeadlessToolResult,\n} from '@agimon-ai/doompi-core/headless';\n\nimport { EditParamsSchema, type EditParams } from '../schemas/editTool';\nimport { executeHashlineEdit } from '../services/editTool';\n\nexport function createHeadlessEditTool(): DoomHeadlessTool<typeof EditParamsSchema> {\n return {\n name: 'edit',\n label: 'edit',\n description:\n 'Edit one file using its exact snapshot hash and inclusive anchors such as 5#abc from read or grep. Each from and to value must contain one anchor, not a pasted block. All ranges refer to the original snapshot. Empty or omitted content deletes a range.',\n promptSnippet: 'Edit files with snapshot-bound hashline ranges',\n promptGuidelines: [\n 'Copy path, hash, and anchors from the latest compatible read or grep result. Re-read after every successful edit.',\n 'Pass one anchor such as 5#abc in each from and to value. Do not paste tagged lines or multiline blocks.',\n ],\n parameters: EditParamsSchema,\n executionMode: 'parallel',\n execute: (\n _toolCallId: string,\n params: EditParams,\n signal: AbortSignal | undefined,\n _onUpdate: ((result: DoomHeadlessToolResult) => void) | undefined,\n context: DoomHeadlessExecutionContext,\n ) => executeHashlineEdit(params, context.cwd, signal),\n };\n}\n"],"mappings":"gIASA,SAAgB,GAAoE,CAClF,MAAO,CACL,KAAM,OACN,MAAO,OACP,YACE,8PACF,cAAe,iDACf,iBAAkB,CAChB,oHACA,yGACF,EACA,WAAY,EACZ,cAAe,WACf,SACE,EACA,EACA,EACA,EACA,IACG,EAAoB,EAAQ,EAAQ,IAAK,CAAM,CACtD,CACF"}
|
package/dist/tools/piEdit.cjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const e=require("../schemas/editTool.cjs"),t=require("../services/editTool/index.cjs");let n=require("@agimon-ai/doompi-ui/hashlineRendering");function r(){return{name:`edit`,label:`edit`,description:`Edit one file using its exact snapshot hash and inclusive anchors such as 5#abc from read or grep. Each from and to value must contain one anchor, not a pasted block. All ranges refer to the original snapshot. Empty or omitted content deletes a range.`,promptSnippet:`Edit files with snapshot-bound hashline ranges`,promptGuidelines:[`Copy path, hash, and anchors from the latest compatible read or grep result. Re-read after every successful edit.`,`Pass one anchor such as 5#abc in each from and to value. Do not paste tagged lines or multiline blocks.`,`Put multiple disjoint changes to one file in one edit call. All anchors must describe the original snapshot.`,`Omit content or pass an empty string to delete an inclusive range. Merge overlapping ranges before calling edit.`],parameters:e.EditParamsSchema,executionMode:`parallel`,renderShell:`self`,async execute(e,n,r,i,a){return t.executeHashlineEdit(n,a.cwd,r)},renderCall(e,t){let r=e,i=r.edits.length;return(0,n.renderHashlineCall)(`edit`,r.path,[`${i} ${i===1?`range`:`ranges`}`],t)},renderResult(e,t,r,i){let a=i.args;return(0,n.renderHashlineEditResult)(a.path,e,t,r,i)}}}exports.createHashlineEditTool=r,exports.executeHashlineEdit=t.executeHashlineEdit;
|
|
2
|
-
//# sourceMappingURL=piEdit.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"piEdit.cjs","names":["EditParamsSchema","executeHashlineEdit","renderHashlineCall","renderHashlineEditResult"],"sources":["../../src/tools/piEdit.ts"],"sourcesContent":["import { renderHashlineCall, renderHashlineEditResult } from '@agimon-ai/doompi-ui/hashlineRendering';\nimport type { ToolDefinition } from '@earendil-works/pi-coding-agent';\n\nimport { EditParamsSchema, type EditParams } from '../schemas/editTool';\nimport { executeHashlineEdit } from '../services/editTool';\n\nexport { assertNotAborted, executeHashlineEdit } from '../services/editTool';\n\nexport function createHashlineEditTool(): ToolDefinition<typeof EditParamsSchema> {\n return {\n name: 'edit',\n label: 'edit',\n description:\n 'Edit one file using its exact snapshot hash and inclusive anchors such as 5#abc from read or grep. Each from and to value must contain one anchor, not a pasted block. All ranges refer to the original snapshot. Empty or omitted content deletes a range.',\n promptSnippet: 'Edit files with snapshot-bound hashline ranges',\n promptGuidelines: [\n 'Copy path, hash, and anchors from the latest compatible read or grep result. Re-read after every successful edit.',\n 'Pass one anchor such as 5#abc in each from and to value. Do not paste tagged lines or multiline blocks.',\n 'Put multiple disjoint changes to one file in one edit call. All anchors must describe the original snapshot.',\n 'Omit content or pass an empty string to delete an inclusive range. Merge overlapping ranges before calling edit.',\n ],\n parameters: EditParamsSchema,\n executionMode: 'parallel',\n renderShell: 'self',\n async execute(_toolCallId, params, signal, _onUpdate, ctx) {\n return executeHashlineEdit(params as EditParams, ctx.cwd, signal);\n },\n renderCall(args, theme) {\n const input = args as EditParams;\n const count = input.edits.length;\n return renderHashlineCall('edit', input.path, [`${count} ${count === 1 ? 'range' : 'ranges'}`], theme);\n },\n renderResult(result, options, theme, context) {\n const input = context.args as EditParams;\n return renderHashlineEditResult(input.path, result, options, theme, context);\n },\n };\n}\n"],"mappings":"+IAQA,SAAgB,GAAkE,CAChF,MAAO,CACL,KAAM,OACN,MAAO,OACP,YACE,8PACF,cAAe,iDACf,iBAAkB,CAChB,oHACA,0GACA,+GACA,kHACF,EACA,WAAYA,EAAAA,iBACZ,cAAe,WACf,YAAa,OACb,MAAM,QAAQ,EAAa,EAAQ,EAAQ,EAAW,EAAK,CACzD,OAAOC,EAAAA,oBAAoB,EAAsB,EAAI,IAAK,CAAM,CAClE,EACA,WAAW,EAAM,EAAO,CACtB,IAAM,EAAQ,EACR,EAAQ,EAAM,MAAM,OAC1B,OAAA,EAAOC,EAAAA,mBAAAA,CAAmB,OAAQ,EAAM,KAAM,CAAC,GAAG,EAAM,GAAG,IAAU,EAAI,QAAU,UAAU,EAAG,CAAK,CACvG,EACA,aAAa,EAAQ,EAAS,EAAO,EAAS,CAC5C,IAAM,EAAQ,EAAQ,KACtB,OAAA,EAAOC,EAAAA,yBAAAA,CAAyB,EAAM,KAAM,EAAQ,EAAS,EAAO,CAAO,CAC7E,CACF,CACF"}
|
package/dist/tools/piEdit.d.cts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { EditParamsSchema } from "../schemas/editTool.cjs";
|
|
2
|
-
import { executeHashlineEdit } from "../services/editTool/index.cjs";
|
|
3
|
-
import { ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
4
|
-
//#region src/tools/piEdit.d.ts
|
|
5
|
-
export declare function createHashlineEditTool(): ToolDefinition<typeof EditParamsSchema>;
|
|
6
|
-
//#endregion
|
|
7
|
-
export { executeHashlineEdit };
|
|
8
|
-
//# sourceMappingURL=piEdit.d.cts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"piEdit.d.cts","names":[],"sources":["../../src/tools/piEdit.ts"],"mappings":";;;;wBAQgB,0BAA0B,sBAAsB"}
|
package/dist/tools/piEdit.d.mts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { EditParamsSchema } from "../schemas/editTool.mjs";
|
|
2
|
-
import { executeHashlineEdit } from "../services/editTool/index.mjs";
|
|
3
|
-
import { ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
4
|
-
//#region src/tools/piEdit.d.ts
|
|
5
|
-
export declare function createHashlineEditTool(): ToolDefinition<typeof EditParamsSchema>;
|
|
6
|
-
//#endregion
|
|
7
|
-
export { executeHashlineEdit };
|
|
8
|
-
//# sourceMappingURL=piEdit.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"piEdit.d.mts","names":[],"sources":["../../src/tools/piEdit.ts"],"mappings":";;;;wBAQgB,0BAA0B,sBAAsB"}
|
package/dist/tools/piEdit.mjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{EditParamsSchema as e}from"../schemas/editTool.mjs";import{executeHashlineEdit as t}from"../services/editTool/index.mjs";import{renderHashlineCall as n,renderHashlineEditResult as r}from"@agimon-ai/doompi-ui/hashlineRendering";function i(){return{name:`edit`,label:`edit`,description:`Edit one file using its exact snapshot hash and inclusive anchors such as 5#abc from read or grep. Each from and to value must contain one anchor, not a pasted block. All ranges refer to the original snapshot. Empty or omitted content deletes a range.`,promptSnippet:`Edit files with snapshot-bound hashline ranges`,promptGuidelines:[`Copy path, hash, and anchors from the latest compatible read or grep result. Re-read after every successful edit.`,`Pass one anchor such as 5#abc in each from and to value. Do not paste tagged lines or multiline blocks.`,`Put multiple disjoint changes to one file in one edit call. All anchors must describe the original snapshot.`,`Omit content or pass an empty string to delete an inclusive range. Merge overlapping ranges before calling edit.`],parameters:e,executionMode:`parallel`,renderShell:`self`,async execute(e,n,r,i,a){return t(n,a.cwd,r)},renderCall(e,t){let r=e,i=r.edits.length;return n(`edit`,r.path,[`${i} ${i===1?`range`:`ranges`}`],t)},renderResult(e,t,n,i){let a=i.args;return r(a.path,e,t,n,i)}}}export{i as createHashlineEditTool,t as executeHashlineEdit};
|
|
2
|
-
//# sourceMappingURL=piEdit.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"piEdit.mjs","names":[],"sources":["../../src/tools/piEdit.ts"],"sourcesContent":["import { renderHashlineCall, renderHashlineEditResult } from '@agimon-ai/doompi-ui/hashlineRendering';\nimport type { ToolDefinition } from '@earendil-works/pi-coding-agent';\n\nimport { EditParamsSchema, type EditParams } from '../schemas/editTool';\nimport { executeHashlineEdit } from '../services/editTool';\n\nexport { assertNotAborted, executeHashlineEdit } from '../services/editTool';\n\nexport function createHashlineEditTool(): ToolDefinition<typeof EditParamsSchema> {\n return {\n name: 'edit',\n label: 'edit',\n description:\n 'Edit one file using its exact snapshot hash and inclusive anchors such as 5#abc from read or grep. Each from and to value must contain one anchor, not a pasted block. All ranges refer to the original snapshot. Empty or omitted content deletes a range.',\n promptSnippet: 'Edit files with snapshot-bound hashline ranges',\n promptGuidelines: [\n 'Copy path, hash, and anchors from the latest compatible read or grep result. Re-read after every successful edit.',\n 'Pass one anchor such as 5#abc in each from and to value. Do not paste tagged lines or multiline blocks.',\n 'Put multiple disjoint changes to one file in one edit call. All anchors must describe the original snapshot.',\n 'Omit content or pass an empty string to delete an inclusive range. Merge overlapping ranges before calling edit.',\n ],\n parameters: EditParamsSchema,\n executionMode: 'parallel',\n renderShell: 'self',\n async execute(_toolCallId, params, signal, _onUpdate, ctx) {\n return executeHashlineEdit(params as EditParams, ctx.cwd, signal);\n },\n renderCall(args, theme) {\n const input = args as EditParams;\n const count = input.edits.length;\n return renderHashlineCall('edit', input.path, [`${count} ${count === 1 ? 'range' : 'ranges'}`], theme);\n },\n renderResult(result, options, theme, context) {\n const input = context.args as EditParams;\n return renderHashlineEditResult(input.path, result, options, theme, context);\n },\n };\n}\n"],"mappings":"0OAQA,SAAgB,GAAkE,CAChF,MAAO,CACL,KAAM,OACN,MAAO,OACP,YACE,8PACF,cAAe,iDACf,iBAAkB,CAChB,oHACA,0GACA,+GACA,kHACF,EACA,WAAY,EACZ,cAAe,WACf,YAAa,OACb,MAAM,QAAQ,EAAa,EAAQ,EAAQ,EAAW,EAAK,CACzD,OAAO,EAAoB,EAAsB,EAAI,IAAK,CAAM,CAClE,EACA,WAAW,EAAM,EAAO,CACtB,IAAM,EAAQ,EACR,EAAQ,EAAM,MAAM,OAC1B,OAAO,EAAmB,OAAQ,EAAM,KAAM,CAAC,GAAG,EAAM,GAAG,IAAU,EAAI,QAAU,UAAU,EAAG,CAAK,CACvG,EACA,aAAa,EAAQ,EAAS,EAAO,EAAS,CAC5C,IAAM,EAAQ,EAAQ,KACtB,OAAO,EAAyB,EAAM,KAAM,EAAQ,EAAS,EAAO,CAAO,CAC7E,CACF,CACF"}
|
package/src/extensions/web.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { defineWebPlugin } from '@agimon-ai/doompi-core/web';
|
|
2
|
-
|
|
3
|
-
import { EditToolMessage } from '../web/components/EditToolMessage';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* This package's cockpit presence: the edit tool's timeline card, the web
|
|
7
|
-
* half of the TUI's renderCall and renderResult for hashline edits.
|
|
8
|
-
*/
|
|
9
|
-
export const webPlugin = defineWebPlugin({
|
|
10
|
-
id: 'edit',
|
|
11
|
-
session: {
|
|
12
|
-
toolRenderers: [{ tools: ['edit'], message: EditToolMessage }],
|
|
13
|
-
},
|
|
14
|
-
});
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
import type { ToolMessageRenderProps } from '@agimon-ai/doompi-core/web';
|
|
2
|
-
import {
|
|
3
|
-
collapseLines,
|
|
4
|
-
MessageItem,
|
|
5
|
-
MessageItemBody,
|
|
6
|
-
MessageItemHeader,
|
|
7
|
-
MessageItemStatus,
|
|
8
|
-
SyntaxLine,
|
|
9
|
-
ToolPathLink,
|
|
10
|
-
toolTone,
|
|
11
|
-
useSyntaxLines,
|
|
12
|
-
} from '@agimon-ai/doompi-web-components';
|
|
13
|
-
|
|
14
|
-
import { type DiffRow, editCallView, editResultView, resultTextLines } from '../lib/editToolView';
|
|
15
|
-
|
|
16
|
-
/** Diff rows shown until the item expands; about what the old scroll box held. */
|
|
17
|
-
const COLLAPSED_ROWS = 24;
|
|
18
|
-
|
|
19
|
-
// Doom carries a diff on the background the way Magit does: a green wash on
|
|
20
|
-
// added rows, a red wash on removed ones, and the foreground left to the text.
|
|
21
|
-
const ROW_TONE: Readonly<Record<DiffRow['marker'], string>> = {
|
|
22
|
-
'+': 'bg-doom-tint-green text-doom-green',
|
|
23
|
-
'-': 'bg-doom-tint-red text-doom-red',
|
|
24
|
-
' ': 'text-doom-dim',
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* The banded rows, and the grammar over them.
|
|
29
|
-
*
|
|
30
|
-
* Its own component because the colours come from a hook, and the body that
|
|
31
|
-
* renders these rows is chosen inside a render prop. The rows are parsed as
|
|
32
|
-
* one document: a diff is not a file, so a replaced line is seen twice and a
|
|
33
|
-
* split string can colour oddly, which costs a token here and there and never
|
|
34
|
-
* costs the reader the text. The `+` and `-` wash stays underneath, so what
|
|
35
|
-
* changed is still legible when the grammar has coloured the foreground.
|
|
36
|
-
*/
|
|
37
|
-
function DiffRows({ rows, gutter, path }: { rows: readonly DiffRow[]; gutter: number; path: string }) {
|
|
38
|
-
const spans = useSyntaxLines(rows.map((row) => row.content).join('\n'), { path });
|
|
39
|
-
return (
|
|
40
|
-
<>
|
|
41
|
-
{rows.map((row, index) => (
|
|
42
|
-
<span key={`${String(index)}-${row.lineNumber}`} className={`flex gap-2 ${ROW_TONE[row.marker]}`}>
|
|
43
|
-
<span className="shrink-0 text-right text-doom-faint" style={{ width: `${String(gutter)}ch` }}>
|
|
44
|
-
{row.lineNumber}
|
|
45
|
-
</span>
|
|
46
|
-
<span className="w-2 shrink-0">{row.marker === ' ' ? '' : row.marker}</span>
|
|
47
|
-
<SyntaxLine spans={spans?.[index]} text={row.content} className="min-w-0 whitespace-pre-wrap break-words" />
|
|
48
|
-
</span>
|
|
49
|
-
))}
|
|
50
|
-
</>
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* The edit tool's timeline item: `path · N ranges` in the header; the display
|
|
56
|
-
* diff from the result's details, banded by row, in the body. A successful
|
|
57
|
-
* edit whose details never arrived shows nothing, and a failed one shows the
|
|
58
|
-
* tool's message in red.
|
|
59
|
-
*/
|
|
60
|
-
export function EditToolMessage({
|
|
61
|
-
args,
|
|
62
|
-
result,
|
|
63
|
-
output,
|
|
64
|
-
running,
|
|
65
|
-
isError,
|
|
66
|
-
fileTabFor,
|
|
67
|
-
openTransientTab,
|
|
68
|
-
}: ToolMessageRenderProps) {
|
|
69
|
-
const call = editCallView(args);
|
|
70
|
-
const view = result === null || isError ? undefined : editResultView(result);
|
|
71
|
-
// The file this edit lands in, opened from the header rather than found
|
|
72
|
-
// again in a file list; plain text when nothing installed can show it.
|
|
73
|
-
const tab = fileTabFor(call.path);
|
|
74
|
-
return (
|
|
75
|
-
<MessageItem
|
|
76
|
-
tone={toolTone({ running, isError })}
|
|
77
|
-
expandable={view !== undefined && view.rows.length > COLLAPSED_ROWS}
|
|
78
|
-
>
|
|
79
|
-
{({ expanded }) => (
|
|
80
|
-
<>
|
|
81
|
-
<MessageItemHeader title="edit">
|
|
82
|
-
<span data-testid="tool-call-edit" className="flex min-w-0 flex-1 items-center gap-2">
|
|
83
|
-
<ToolPathLink path={call.path} {...(tab === undefined ? {} : { onOpen: () => openTransientTab(tab) })} />
|
|
84
|
-
<span className="shrink-0 text-doom-faint">· {call.ranges}</span>
|
|
85
|
-
</span>
|
|
86
|
-
</MessageItemHeader>
|
|
87
|
-
{isError ? (
|
|
88
|
-
<MessageItemBody data-testid="tool-result-edit" className="flex flex-col">
|
|
89
|
-
<MessageItemStatus tone="error">failed</MessageItemStatus>
|
|
90
|
-
{resultTextLines(result, output).map((line, index) => (
|
|
91
|
-
<span key={`${String(index)}-${line}`} className="whitespace-pre-wrap break-words text-doom-red">
|
|
92
|
-
{line}
|
|
93
|
-
</span>
|
|
94
|
-
))}
|
|
95
|
-
</MessageItemBody>
|
|
96
|
-
) : view === undefined ? (
|
|
97
|
-
running ? (
|
|
98
|
-
<MessageItemBody data-testid="tool-result-edit">
|
|
99
|
-
<MessageItemStatus tone="running">running</MessageItemStatus>
|
|
100
|
-
</MessageItemBody>
|
|
101
|
-
) : null
|
|
102
|
-
) : (
|
|
103
|
-
(() => {
|
|
104
|
-
const { shown, hidden } = collapseLines(view.rows, COLLAPSED_ROWS, expanded);
|
|
105
|
-
return (
|
|
106
|
-
<MessageItemBody data-testid="tool-result-edit" className="flex flex-col font-mono">
|
|
107
|
-
<DiffRows rows={shown} gutter={view.gutter} path={call.path} />
|
|
108
|
-
{hidden > 0 ? (
|
|
109
|
-
<MessageItemStatus expands className="pt-1">
|
|
110
|
-
{hidden} more rows
|
|
111
|
-
</MessageItemStatus>
|
|
112
|
-
) : null}
|
|
113
|
-
</MessageItemBody>
|
|
114
|
-
);
|
|
115
|
-
})()
|
|
116
|
-
)}
|
|
117
|
-
</>
|
|
118
|
-
)}
|
|
119
|
-
</MessageItem>
|
|
120
|
-
);
|
|
121
|
-
}
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import type { ToolResultView } from '@agimon-ai/doompi-core/web';
|
|
2
|
-
|
|
3
|
-
/** Pi emits `+12 text`, `-12 text`, ` 12 text`, and a blank-numbered ` ... ` elision between hunks. */
|
|
4
|
-
const DIFF_ROW_PATTERN = /^([+\- ])( *\d*) (.*)$/u;
|
|
5
|
-
const CONTEXT_MARKER = ' ';
|
|
6
|
-
|
|
7
|
-
export type DiffMarker = '+' | '-' | typeof CONTEXT_MARKER;
|
|
8
|
-
|
|
9
|
-
export interface DiffRow {
|
|
10
|
-
readonly marker: DiffMarker;
|
|
11
|
-
readonly lineNumber: string;
|
|
12
|
-
readonly content: string;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface EditCallView {
|
|
16
|
-
readonly path: string;
|
|
17
|
-
/** `N range` or `N ranges`, the count the TUI's call heading shows. */
|
|
18
|
-
readonly ranges: string;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface EditResultView {
|
|
22
|
-
readonly rows: readonly DiffRow[];
|
|
23
|
-
/** Widest line number among the rows, in characters, sizing the gutter. */
|
|
24
|
-
readonly gutter: number;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/** What the edit call heading shows: the path and how many ranges the call touches. */
|
|
28
|
-
export function editCallView(args: Readonly<Record<string, unknown>>): EditCallView {
|
|
29
|
-
const count = Array.isArray(args.edits) ? args.edits.length : 0;
|
|
30
|
-
return {
|
|
31
|
-
path: typeof args.path === 'string' ? args.path : '',
|
|
32
|
-
ranges: `${count} ${count === 1 ? 'range' : 'ranges'}`,
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function toDiffMarker(value: string | undefined): DiffMarker {
|
|
37
|
-
return value === '+' || value === '-' ? value : CONTEXT_MARKER;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/** Pi's display diff as rows; a line that is not a diff row reads as unnumbered context. */
|
|
41
|
-
export function parseDiffRows(diff: string): DiffRow[] {
|
|
42
|
-
return diff.split('\n').map((line) => {
|
|
43
|
-
const expanded = line.replaceAll('\t', ' ');
|
|
44
|
-
const match = DIFF_ROW_PATTERN.exec(expanded);
|
|
45
|
-
if (!match) return { marker: CONTEXT_MARKER, lineNumber: '', content: expanded };
|
|
46
|
-
return { marker: toDiffMarker(match[1]), lineNumber: (match[2] ?? '').trim(), content: match[3] ?? '' };
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/** The diff a successful edit carries in its details; undefined when the details never arrived. */
|
|
51
|
-
export function editResultView(result: ToolResultView | null): EditResultView | undefined {
|
|
52
|
-
const details = result?.details;
|
|
53
|
-
if (typeof details !== 'object' || details === null) return undefined;
|
|
54
|
-
const diff = (details as { diff?: unknown }).diff;
|
|
55
|
-
if (typeof diff !== 'string' || diff.length === 0) return undefined;
|
|
56
|
-
const rows = parseDiffRows(diff);
|
|
57
|
-
return { rows, gutter: rows.reduce((widest, row) => Math.max(widest, row.lineNumber.length), 1) };
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/** The result's text lines, for the error case where the diff never happened. */
|
|
61
|
-
export function resultTextLines(result: ToolResultView | null, output: string): string[] {
|
|
62
|
-
const text =
|
|
63
|
-
result === null
|
|
64
|
-
? output
|
|
65
|
-
: result.content
|
|
66
|
-
.flatMap((block) => {
|
|
67
|
-
const record =
|
|
68
|
-
typeof block === 'object' && block !== null ? (block as { type?: unknown; text?: unknown }) : {};
|
|
69
|
-
return record.type === 'text' && typeof record.text === 'string' ? [record.text] : [];
|
|
70
|
-
})
|
|
71
|
-
.join('\n');
|
|
72
|
-
const lines = text.replaceAll('\t', ' ').replaceAll('\r\n', '\n').split('\n');
|
|
73
|
-
while (lines.at(-1) === '') lines.pop();
|
|
74
|
-
return lines;
|
|
75
|
-
}
|
package/src/web/tsconfig.json
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2022",
|
|
4
|
-
"lib": ["ES2023", "DOM", "DOM.Iterable"],
|
|
5
|
-
"module": "ESNext",
|
|
6
|
-
"moduleResolution": "Bundler",
|
|
7
|
-
"jsx": "react-jsx",
|
|
8
|
-
"strict": true,
|
|
9
|
-
"noImplicitAny": true,
|
|
10
|
-
"noUnusedLocals": true,
|
|
11
|
-
"noUnusedParameters": true,
|
|
12
|
-
"noImplicitReturns": true,
|
|
13
|
-
"noFallthroughCasesInSwitch": true,
|
|
14
|
-
"noEmit": true,
|
|
15
|
-
"resolveJsonModule": true,
|
|
16
|
-
"esModuleInterop": true,
|
|
17
|
-
"skipLibCheck": true,
|
|
18
|
-
"allowImportingTsExtensions": true,
|
|
19
|
-
"forceConsistentCasingInFileNames": true,
|
|
20
|
-
"types": ["node"]
|
|
21
|
-
},
|
|
22
|
-
"include": [".", "../types", "../extensions/web.ts"]
|
|
23
|
-
}
|