@agimon-ai/doompi-edit 0.0.1-alpha.41 → 0.0.1-alpha.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/api-contracts.cjs +1 -0
- package/dist/api-contracts.d.cts +2 -0
- package/dist/api-contracts.d.mts +2 -0
- package/dist/api-contracts.mjs +1 -0
- package/dist/constants/package.cjs +2 -0
- package/dist/constants/package.cjs.map +1 -0
- package/dist/constants/package.mjs +2 -0
- package/dist/constants/package.mjs.map +1 -0
- package/dist/extensions/pi.cjs +2 -1
- package/dist/extensions/pi.cjs.map +1 -0
- package/dist/extensions/pi.d.cts +5 -2
- package/dist/extensions/pi.d.cts.map +1 -0
- package/dist/extensions/pi.d.mts +5 -2
- package/dist/extensions/pi.d.mts.map +1 -0
- package/dist/extensions/pi.mjs +2 -1
- package/dist/extensions/pi.mjs.map +1 -0
- package/dist/extensions/server.cjs +2 -0
- package/dist/extensions/server.cjs.map +1 -0
- package/dist/extensions/server.d.cts +5 -0
- package/dist/extensions/server.d.cts.map +1 -0
- package/dist/extensions/server.d.mts +5 -0
- package/dist/extensions/server.d.mts.map +1 -0
- package/dist/extensions/server.mjs +2 -0
- package/dist/extensions/server.mjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.mts +4 -3
- package/dist/index.mjs +1 -1
- package/dist/schemas/apiContracts.cjs +2 -0
- package/dist/schemas/apiContracts.cjs.map +1 -0
- package/dist/schemas/apiContracts.d.cts +53 -0
- package/dist/schemas/apiContracts.d.cts.map +1 -0
- package/dist/schemas/apiContracts.d.mts +53 -0
- package/dist/schemas/apiContracts.d.mts.map +1 -0
- package/dist/schemas/apiContracts.mjs +2 -0
- package/dist/schemas/apiContracts.mjs.map +1 -0
- package/dist/services/editTool/index.cjs +9 -0
- package/dist/services/editTool/index.cjs.map +1 -0
- package/dist/{adapters/pi/editTool.d.cts → services/editTool/index.d.cts} +3 -4
- package/dist/services/editTool/index.d.cts.map +1 -0
- package/dist/{adapters/pi/editTool.d.mts → services/editTool/index.d.mts} +3 -4
- package/dist/services/editTool/index.d.mts.map +1 -0
- package/dist/services/editTool/index.mjs +9 -0
- package/dist/services/editTool/index.mjs.map +1 -0
- package/dist/tools/headlessEdit.cjs +2 -0
- package/dist/tools/headlessEdit.cjs.map +1 -0
- package/dist/tools/headlessEdit.d.cts +6 -0
- package/dist/tools/headlessEdit.d.cts.map +1 -0
- package/dist/tools/headlessEdit.d.mts +6 -0
- package/dist/tools/headlessEdit.d.mts.map +1 -0
- package/dist/tools/headlessEdit.mjs +2 -0
- package/dist/tools/headlessEdit.mjs.map +1 -0
- package/dist/tools/piEdit.cjs +2 -0
- package/dist/tools/piEdit.cjs.map +1 -0
- package/dist/tools/piEdit.d.cts +8 -0
- package/dist/tools/piEdit.d.cts.map +1 -0
- package/dist/tools/piEdit.d.mts +8 -0
- package/dist/tools/piEdit.d.mts.map +1 -0
- package/dist/tools/piEdit.mjs +2 -0
- package/dist/tools/piEdit.mjs.map +1 -0
- package/package.json +26 -8
- package/src/extensions/web.ts +14 -0
- package/src/web/components/EditToolMessage.tsx +3 -2
- package/src/web/lib/editToolView.ts +1 -1
- package/src/web/tsconfig.json +1 -1
- package/dist/adapters/pi/editTool.cjs +0 -9
- package/dist/adapters/pi/editTool.cjs.map +0 -1
- package/dist/adapters/pi/editTool.d.cts.map +0 -1
- package/dist/adapters/pi/editTool.d.mts.map +0 -1
- package/dist/adapters/pi/editTool.mjs +0 -9
- package/dist/adapters/pi/editTool.mjs.map +0 -1
- package/dist/adapters/pi/extension.cjs +0 -2
- package/dist/adapters/pi/extension.cjs.map +0 -1
- package/dist/adapters/pi/extension.d.cts +0 -10
- package/dist/adapters/pi/extension.d.cts.map +0 -1
- package/dist/adapters/pi/extension.d.mts +0 -10
- package/dist/adapters/pi/extension.d.mts.map +0 -1
- package/dist/adapters/pi/extension.mjs +0 -2
- package/dist/adapters/pi/extension.mjs.map +0 -1
- package/src/exports/webClient.ts +0 -1
- package/src/web/index.ts +0 -11
package/README.md
CHANGED
|
@@ -77,7 +77,7 @@ boundary.
|
|
|
77
77
|
## Public API
|
|
78
78
|
|
|
79
79
|
```ts
|
|
80
|
-
import { EditParamsSchema, executeHashlineEdit,
|
|
80
|
+
import { EditParamsSchema, executeHashlineEdit, createHashlineEditTool } from '@agimon-ai/doompi-edit';
|
|
81
81
|
import type { EditParams, HashlineRange } from '@agimon-ai/doompi-edit';
|
|
82
82
|
```
|
|
83
83
|
|
|
@@ -95,3 +95,5 @@ Maintained by [Agimon](https://agimon.ai/about).
|
|
|
95
95
|
## License
|
|
96
96
|
|
|
97
97
|
MIT
|
|
98
|
+
|
|
99
|
+
`src/extensions/pi.ts` declares the typed edit override; the helper owns its claim and cleanup. `src/extensions/server.ts` declares the headless tool. Both tool declarations consume `services/editTool`, and reusable factories and schemas are exposed through flat `src/exports`.
|
|
@@ -0,0 +1 @@
|
|
|
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;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{apiContracts as e}from"./schemas/apiContracts.mjs";export{e as apiContracts,e as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package.cjs","names":[],"sources":["../../src/constants/package.ts"],"sourcesContent":["export const PACKAGE_SOURCE = '@agimon-ai/doompi-edit';\n"],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
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
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
const e=require("../
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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
CHANGED
|
@@ -1,2 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pi.d.cts","names":[],"sources":["../../src/extensions/pi.ts"],"mappings":";qBAKa,mFAA2B"}
|
package/dist/extensions/pi.d.mts
CHANGED
|
@@ -1,2 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pi.d.mts","names":[],"sources":["../../src/extensions/pi.ts"],"mappings":";qBAKa,mFAA2B"}
|
package/dist/extensions/pi.mjs
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
import{
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.cts","names":[],"sources":["../../src/extensions/server.ts"],"mappings":";qBAKa,+DAAe"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.mts","names":[],"sources":["../../src/extensions/server.ts"],"mappings":";qBAKa,+DAAe"}
|
|
@@ -0,0 +1,2 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./schemas/editTool.cjs"),t=require("./
|
|
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
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { activateDoomPiEditExtension, installDoomPiEditRuntime } from "./adapters/pi/extension.cjs";
|
|
2
1
|
import { EditParams, EditParamsSchema, HashlineRange, HashlineRangeSchema } from "./schemas/editTool.cjs";
|
|
3
|
-
import { executeHashlineEdit
|
|
4
|
-
|
|
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
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { activateDoomPiEditExtension, installDoomPiEditRuntime } from "./adapters/pi/extension.mjs";
|
|
2
1
|
import { EditParams, EditParamsSchema, HashlineRange, HashlineRangeSchema } from "./schemas/editTool.mjs";
|
|
3
|
-
import { executeHashlineEdit
|
|
4
|
-
|
|
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
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{EditParamsSchema as e,HashlineRangeSchema as t}from"./schemas/editTool.mjs";import{executeHashlineEdit as n
|
|
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};
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiContracts.d.cts","names":[],"sources":["../../src/schemas/apiContracts.ts"],"mappings":";;qBAGa"}
|
|
@@ -0,0 +1,53 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiContracts.d.mts","names":[],"sources":["../../src/schemas/apiContracts.ts"],"mappings":";;qBAGa"}
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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,7 +1,6 @@
|
|
|
1
1
|
import { EditParams } from "../../schemas/editTool.cjs";
|
|
2
|
-
import { EditToolDetails
|
|
3
|
-
//#region src/
|
|
4
|
-
export declare function registerHashlineEditTool(pi: Pick<ExtensionAPI, 'registerTool'>): void;
|
|
2
|
+
import { EditToolDetails } from "@earendil-works/pi-coding-agent";
|
|
3
|
+
//#region src/services/editTool/index.d.ts
|
|
5
4
|
export declare function executeHashlineEdit(params: EditParams, cwd: string, signal: AbortSignal | undefined): Promise<{
|
|
6
5
|
content: [{
|
|
7
6
|
type: 'text';
|
|
@@ -10,4 +9,4 @@ export declare function executeHashlineEdit(params: EditParams, cwd: string, sig
|
|
|
10
9
|
details: EditToolDetails;
|
|
11
10
|
}>;
|
|
12
11
|
//#endregion
|
|
13
|
-
//# sourceMappingURL=
|
|
12
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
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,7 +1,6 @@
|
|
|
1
1
|
import { EditParams } from "../../schemas/editTool.mjs";
|
|
2
|
-
import { EditToolDetails
|
|
3
|
-
//#region src/
|
|
4
|
-
export declare function registerHashlineEditTool(pi: Pick<ExtensionAPI, 'registerTool'>): void;
|
|
2
|
+
import { EditToolDetails } from "@earendil-works/pi-coding-agent";
|
|
3
|
+
//#region src/services/editTool/index.d.ts
|
|
5
4
|
export declare function executeHashlineEdit(params: EditParams, cwd: string, signal: AbortSignal | undefined): Promise<{
|
|
6
5
|
content: [{
|
|
7
6
|
type: 'text';
|
|
@@ -10,4 +9,4 @@ export declare function executeHashlineEdit(params: EditParams, cwd: string, sig
|
|
|
10
9
|
details: EditToolDetails;
|
|
11
10
|
}>;
|
|
12
11
|
//#endregion
|
|
13
|
-
//# sourceMappingURL=
|
|
12
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headlessEdit.d.cts","names":[],"sources":["../../src/tools/headlessEdit.ts"],"mappings":";;;wBASgB,0BAA0B,wBAAwB"}
|
|
@@ -0,0 +1,6 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headlessEdit.d.mts","names":[],"sources":["../../src/tools/headlessEdit.ts"],"mappings":";;;wBASgB,0BAA0B,wBAAwB"}
|
|
@@ -0,0 +1,2 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"piEdit.d.cts","names":[],"sources":["../../src/tools/piEdit.ts"],"mappings":";;;;wBAQgB,0BAA0B,sBAAsB"}
|
|
@@ -0,0 +1,8 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"piEdit.d.mts","names":[],"sources":["../../src/tools/piEdit.ts"],"mappings":";;;;wBAQgB,0BAA0B,sBAAsB"}
|
|
@@ -0,0 +1,2 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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/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.43",
|
|
4
4
|
"description": "Snapshot-bound hashline edit tool for Pi and DoomPi.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"files": [
|
|
27
27
|
"dist",
|
|
28
28
|
"src/web",
|
|
29
|
-
"src/
|
|
29
|
+
"src/extensions/web.ts",
|
|
30
30
|
"!src/web/**/*.stories.tsx"
|
|
31
31
|
],
|
|
32
32
|
"type": "module",
|
|
@@ -44,6 +44,11 @@
|
|
|
44
44
|
"import": "./dist/extensions/pi.mjs",
|
|
45
45
|
"require": "./dist/extensions/pi.cjs"
|
|
46
46
|
},
|
|
47
|
+
"./extensions/server": {
|
|
48
|
+
"types": "./dist/extensions/server.d.mts",
|
|
49
|
+
"import": "./dist/extensions/server.mjs",
|
|
50
|
+
"require": "./dist/extensions/server.cjs"
|
|
51
|
+
},
|
|
47
52
|
"./package.json": "./package.json"
|
|
48
53
|
},
|
|
49
54
|
"publishConfig": {
|
|
@@ -52,11 +57,10 @@
|
|
|
52
57
|
"dependencies": {
|
|
53
58
|
"@deepseek-ai/cordis": "4.0.2",
|
|
54
59
|
"typebox": "1.3.25",
|
|
55
|
-
"@agimon-ai/doompi-
|
|
56
|
-
"@agimon-ai/doompi-hashline": "0.0.1-alpha.
|
|
57
|
-
"@agimon-ai/doompi-
|
|
58
|
-
"@agimon-ai/doompi-web-
|
|
59
|
-
"@agimon-ai/doompi-ui": "0.0.1-alpha.69"
|
|
60
|
+
"@agimon-ai/doompi-core": "0.0.1-alpha.71",
|
|
61
|
+
"@agimon-ai/doompi-hashline": "0.0.1-alpha.40",
|
|
62
|
+
"@agimon-ai/doompi-ui": "0.0.1-alpha.71",
|
|
63
|
+
"@agimon-ai/doompi-web-components": "0.0.1-alpha.29"
|
|
60
64
|
},
|
|
61
65
|
"devDependencies": {
|
|
62
66
|
"@earendil-works/pi-coding-agent": "0.85.1",
|
|
@@ -87,10 +91,24 @@
|
|
|
87
91
|
"engines": {
|
|
88
92
|
"node": ">=22.19.0"
|
|
89
93
|
},
|
|
94
|
+
"doompiServer": {
|
|
95
|
+
"entry": "./src/extensions/server.ts",
|
|
96
|
+
"dist": "./dist/extensions/server.mjs",
|
|
97
|
+
"scopes": [
|
|
98
|
+
"session"
|
|
99
|
+
],
|
|
100
|
+
"contracts": {
|
|
101
|
+
"entry": "./src/exports/apiContracts.ts",
|
|
102
|
+
"dist": "./dist/api-contracts.mjs"
|
|
103
|
+
}
|
|
104
|
+
},
|
|
90
105
|
"doompiWeb": {
|
|
91
106
|
"pluginId": "edit",
|
|
92
107
|
"channels": [],
|
|
93
|
-
"client": "./src/
|
|
108
|
+
"client": "./src/extensions/web.ts",
|
|
109
|
+
"scopes": [
|
|
110
|
+
"session"
|
|
111
|
+
]
|
|
94
112
|
},
|
|
95
113
|
"pi": {
|
|
96
114
|
"extensions": [
|
|
@@ -0,0 +1,14 @@
|
|
|
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,3 +1,4 @@
|
|
|
1
|
+
import type { ToolMessageRenderProps } from '@agimon-ai/doompi-core/web';
|
|
1
2
|
import {
|
|
2
3
|
collapseLines,
|
|
3
4
|
MessageItem,
|
|
@@ -9,8 +10,8 @@ import {
|
|
|
9
10
|
toolTone,
|
|
10
11
|
useSyntaxLines,
|
|
11
12
|
} from '@agimon-ai/doompi-web-components';
|
|
12
|
-
|
|
13
|
-
import { type DiffRow, editCallView, editResultView, resultTextLines } from '../lib/editToolView
|
|
13
|
+
|
|
14
|
+
import { type DiffRow, editCallView, editResultView, resultTextLines } from '../lib/editToolView';
|
|
14
15
|
|
|
15
16
|
/** Diff rows shown until the item expands; about what the old scroll box held. */
|
|
16
17
|
const COLLAPSED_ROWS = 24;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ToolResultView } from '@agimon-ai/doompi-web
|
|
1
|
+
import type { ToolResultView } from '@agimon-ai/doompi-core/web';
|
|
2
2
|
|
|
3
3
|
/** Pi emits `+12 text`, `-12 text`, ` 12 text`, and a blank-numbered ` ... ` elision between hunks. */
|
|
4
4
|
const DIFF_ROW_PATTERN = /^([+\- ])( *\d*) (.*)$/u;
|
package/src/web/tsconfig.json
CHANGED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
const e=require("../../schemas/editTool.cjs");let t=require("node:fs"),n=require("node:fs/promises"),r=require("@agimon-ai/doompi-hashline"),i=require("@agimon-ai/doompi-hashline/files"),a=require("@agimon-ai/doompi-ui/hashlineRendering"),o=require("@earendil-works/pi-coding-agent");const s=Buffer.from([239,187,191]);function c(t){t.registerTool({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,t,n,r,i){return l(t,i.cwd,n)},renderCall(e,t){let n=e,r=n.edits.length;return(0,a.renderHashlineCall)(`edit`,n.path,[`${r} ${r===1?`range`:`ranges`}`],t)},renderResult(e,t,n,r){let i=r.args;return(0,a.renderHashlineEditResult)(i.path,e,t,n,r)}})}async function l(e,a,c){let l=(0,i.resolveInputPath)(e.path,a),f=(0,r.normalizeFileTag)(e.hash);return(0,o.withFileMutationQueue)(l,async()=>{u(c),await(0,n.access)(l,t.constants.R_OK|t.constants.W_OK);let p=await(0,n.readFile)(l);u(c);let m=(0,i.computeFileTag)(p);if(m!==f)throw Error(`Stale file hash ${f}. Current hash is ${m}. Re-read the file and retry.`);let h=p.subarray(0,s.length).equals(s),g=(0,i.decodeUtf8)(p,e.path),_=(0,r.stripBom)(g),v=(0,r.normalizeToLf)(_),y=(0,r.applyHashlineEdits)(v,e.edits),b=d(_,y.edits);if((0,r.normalizeToLf)(b)!==y.content)throw Error(`Could not preserve the file line endings safely. The file was not changed.`);let x=(0,o.generateDiffString)(v,y.content),S=(0,o.generateUnifiedPatch)((0,i.displayPath)(l,a),v,y.content),C={diff:x.diff,patch:S,firstChangedLine:x.firstChangedLine};if(u(c),!(await(0,n.readFile)(l)).equals(p))throw Error(`The file changed while the edit was being prepared. Re-read it and retry.`);if(u(c),y.content!==v){let e=Buffer.from(`${h?``:``}${b}`,`utf8`);await(0,n.writeFile)(l,e)}let w=y.edits.length,T=w===1?`range`:`ranges`;return{content:[{type:`text`,text:`${y.content===v?`No changes needed in ${e.path}.`:`Edited ${e.path} (${w} ${T}).`} Re-read before editing it again.`}],details:C}})}function u(e){if(e?.aborted)throw Error(`Operation aborted`)}function d(e,t){let n=f(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=p(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 f(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 p(e){if(e===null||e===``)return[];let t=(0,r.normalizeToLf)(e),n=t.endsWith(`
|
|
7
|
-
`)?t.slice(0,-1):t;return n===``?[]:n.split(`
|
|
8
|
-
`)}exports.executeHashlineEdit=l,exports.registerHashlineEditTool=c;
|
|
9
|
-
//# sourceMappingURL=editTool.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"editTool.cjs","names":["EditParamsSchema","renderHashlineCall","renderHashlineEditResult","resolveInputPath","normalizeFileTag","withFileMutationQueue","access","constants","readFile","computeFileTag","decodeUtf8","stripBom","normalizeToLf","applyHashlineEdits","generateDiffString","generateUnifiedPatch","displayPath","writeFile"],"sources":["../../../src/adapters/pi/editTool.ts"],"sourcesContent":["import { constants } from 'node:fs';\nimport { access, readFile, writeFile } from 'node:fs/promises';\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 { renderHashlineCall, renderHashlineEditResult } from '@agimon-ai/doompi-ui/hashlineRendering';\nimport {\n generateDiffString,\n generateUnifiedPatch,\n withFileMutationQueue,\n type EditToolDetails,\n type ExtensionAPI,\n} from '@earendil-works/pi-coding-agent';\nimport { EditParamsSchema, type EditParams } from '../../schemas/editTool.ts';\n\nconst UTF8_BOM = Buffer.from([0xef, 0xbb, 0xbf]);\n\nexport function registerHashlineEditTool(pi: Pick<ExtensionAPI, 'registerTool'>): void {\n pi.registerTool({\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\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, UTF8_BOM.length).equals(UTF8_BOM);\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 assertNotAborted(signal: AbortSignal | undefined): void {\n if (signal?.aborted) throw new Error('Operation aborted');\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 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"editTool.d.cts","names":[],"sources":["../../../src/adapters/pi/editTool.ts"],"mappings":";;;wBAsBgB,yBAAyB,IAAI,KAAK;wBA+B5B,oBACpB,QAAQ,YACR,aACA,QAAQ,0BACP;EAAU;IAAY;IAAc;;EAAiB,SAAS"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"editTool.d.mts","names":[],"sources":["../../../src/adapters/pi/editTool.ts"],"mappings":";;;wBAsBgB,yBAAyB,IAAI,KAAK;wBA+B5B,oBACpB,QAAQ,YACR,aACA,QAAQ,0BACP;EAAU;IAAY;IAAc;;EAAiB,SAAS"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import{EditParamsSchema as e}from"../../schemas/editTool.mjs";import{constants as t}from"node:fs";import{access as n,readFile as r,writeFile as i}from"node:fs/promises";import{applyHashlineEdits as a,normalizeFileTag as o,normalizeToLf as s,stripBom as c}from"@agimon-ai/doompi-hashline";import{computeFileTag as l,decodeUtf8 as u,displayPath as d,resolveInputPath as f}from"@agimon-ai/doompi-hashline/files";import{renderHashlineCall as p,renderHashlineEditResult as m}from"@agimon-ai/doompi-ui/hashlineRendering";import{generateDiffString as h,generateUnifiedPatch as g,withFileMutationQueue as _}from"@earendil-works/pi-coding-agent";const v=Buffer.from([239,187,191]);function y(t){t.registerTool({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,t,n,r,i){return b(t,i.cwd,n)},renderCall(e,t){let n=e,r=n.edits.length;return p(`edit`,n.path,[`${r} ${r===1?`range`:`ranges`}`],t)},renderResult(e,t,n,r){let i=r.args;return m(i.path,e,t,n,r)}})}async function b(e,p,m){let y=f(e.path,p),b=o(e.hash);return _(y,async()=>{x(m),await n(y,t.R_OK|t.W_OK);let o=await r(y);x(m);let f=l(o);if(f!==b)throw Error(`Stale file hash ${b}. Current hash is ${f}. Re-read the file and retry.`);let _=o.subarray(0,v.length).equals(v),C=u(o,e.path),w=c(C),T=s(w),E=a(T,e.edits),D=S(w,E.edits);if(s(D)!==E.content)throw Error(`Could not preserve the file line endings safely. The file was not changed.`);let O=h(T,E.content),k=g(d(y,p),T,E.content),A={diff:O.diff,patch:k,firstChangedLine:O.firstChangedLine};if(x(m),!(await r(y)).equals(o))throw Error(`The file changed while the edit was being prepared. Re-read it and retry.`);if(x(m),E.content!==T){let e=Buffer.from(`${_?``:``}${D}`,`utf8`);await i(y,e)}let j=E.edits.length,M=j===1?`range`:`ranges`;return{content:[{type:`text`,text:`${E.content===T?`No changes needed in ${e.path}.`:`Edited ${e.path} (${j} ${M}).`} Re-read before editing it again.`}],details:A}})}function x(e){if(e?.aborted)throw Error(`Operation aborted`)}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=w(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 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 w(e){if(e===null||e===``)return[];let t=s(e),n=t.endsWith(`
|
|
7
|
-
`)?t.slice(0,-1):t;return n===``?[]:n.split(`
|
|
8
|
-
`)}export{b as executeHashlineEdit,y as registerHashlineEditTool};
|
|
9
|
-
//# sourceMappingURL=editTool.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"editTool.mjs","names":[],"sources":["../../../src/adapters/pi/editTool.ts"],"sourcesContent":["import { constants } from 'node:fs';\nimport { access, readFile, writeFile } from 'node:fs/promises';\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 { renderHashlineCall, renderHashlineEditResult } from '@agimon-ai/doompi-ui/hashlineRendering';\nimport {\n generateDiffString,\n generateUnifiedPatch,\n withFileMutationQueue,\n type EditToolDetails,\n type ExtensionAPI,\n} from '@earendil-works/pi-coding-agent';\nimport { EditParamsSchema, type EditParams } from '../../schemas/editTool.ts';\n\nconst UTF8_BOM = Buffer.from([0xef, 0xbb, 0xbf]);\n\nexport function registerHashlineEditTool(pi: Pick<ExtensionAPI, 'registerTool'>): void {\n pi.registerTool({\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\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, UTF8_BOM.length).equals(UTF8_BOM);\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 assertNotAborted(signal: AbortSignal | undefined): void {\n if (signal?.aborted) throw new Error('Operation aborted');\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":"6nBAoBA,MAAM,EAAW,OAAO,KAAK,CAAC,IAAM,IAAM,GAAI,CAAC,EAE/C,SAAgB,EAAyB,EAA8C,CACrF,EAAG,aAAa,CACd,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,CAAC,CACH,CAEA,eAAsB,EACpB,EACA,EACA,EACkF,CAClF,IAAM,EAAe,EAAiB,EAAO,KAAM,CAAG,EAChD,EAAe,EAAiB,EAAO,IAAI,EACjD,OAAO,EAAsB,EAAc,SAAY,CACrD,EAAiB,CAAM,EACvB,MAAM,EAAO,EAAc,EAAU,KAAO,EAAU,IAAI,EAC1D,IAAM,EAAc,MAAM,EAAS,CAAY,EAC/C,EAAiB,CAAM,EAEvB,IAAM,EAAa,EAAe,CAAW,EAC7C,GAAI,IAAe,EACjB,MAAU,MAAM,mBAAmB,EAAa,oBAAoB,EAAW,8BAA8B,EAG/G,IAAM,EAAS,EAAY,SAAS,EAAG,EAAS,MAAM,CAAC,CAAC,OAAO,CAAQ,EACjE,EAAU,EAAW,EAAa,EAAO,IAAI,EAC7C,EAAa,EAAS,CAAO,EAC7B,EAAS,EAAc,CAAU,EACjC,EAAU,EAAmB,EAAQ,EAAO,KAAK,EACjD,EAAa,EAA2B,EAAY,EAAQ,KAAK,EACvE,GAAI,EAAc,CAAU,IAAM,EAAQ,QACxC,MAAU,MAAM,4EAA4E,EAE9F,IAAM,EAAO,EAAmB,EAAQ,EAAQ,OAAO,EACjD,EAAQ,EAAqB,EAAY,EAAc,CAAG,EAAG,EAAQ,EAAQ,OAAO,EACpF,EAA2B,CAAE,KAAM,EAAK,KAAM,QAAO,iBAAkB,EAAK,gBAAiB,EAInG,GAFA,EAAiB,CAAM,EAEnB,EAAC,MADsB,EAAS,CAAY,EAAA,CAC9B,OAAO,CAAW,EAClC,MAAU,MAAM,2EAA2E,EAI7F,GAFA,EAAiB,CAAM,EAEnB,EAAQ,UAAY,EAAQ,CAC9B,IAAM,EAAS,OAAO,KAAK,GAAG,EAAS,IAAW,KAAK,IAAc,MAAM,EAC3E,MAAM,EAAU,EAAc,CAAM,CACtC,CAEA,IAAM,EAAQ,EAAQ,MAAM,OACtB,EAAO,IAAU,EAAI,QAAU,SAGrC,MAAO,CAAE,QAAS,CAAC,CAAE,KAAM,OAAQ,KAAM,GADvC,EAAQ,UAAY,EAAS,wBAAwB,EAAO,KAAK,GAAK,UAAU,EAAO,KAAK,IAAI,EAAM,GAAG,EAAK,IAC5D,kCAAmC,CAAC,EAAG,SAAQ,CACrG,CAAC,CACH,CAOA,SAAS,EAAiB,EAAuC,CAC/D,GAAI,GAAQ,QAAS,MAAU,MAAM,mBAAmB,CAC1D,CAEA,SAAS,EAA2B,EAAkB,EAAgD,CACpG,IAAM,EAAS,EAAc,CAAQ,EAC/B,EAAgB,EAAO,KAAM,GAAU,EAAM,SAAW,EAAE,CAAC,EAAE,QAAU;EAC7E,IAAK,IAAM,IAAQ,CAAC,GAAG,CAAK,CAAC,CAAC,QAAQ,EAAG,CACvC,IAAM,EAAQ,EAAK,KAAK,KAAO,EACzB,EAAQ,EAAK,GAAG,KAAO,EAAK,KAAK,KAAO,EACxC,EAAU,EAAO,MAAM,EAAO,EAAQ,CAAK,EAC3C,EAAkB,EAAQ,GAAG,EAAE,CAAC,EAAE,QAAU,GAC5C,EAAiB,EAAQ,KAAM,GAAU,EAAM,SAAW,EAAE,CAAC,EAAE,QAAU,EACzE,EAAQ,EAAiB,EAAK,OAAO,EAC3C,GAAI,EAAM,SAAW,GAAK,EAAQ,GAAG,EAAE,CAAC,EAAE,SAAW,IAAM,EAAQ,EAAG,CACpE,IAAM,EAAW,EAAO,EAAQ,GAC5B,IAAU,EAAO,EAAQ,GAAK,CAAE,GAAG,EAAU,OAAQ,EAAG,EAC9D,CACA,IAAM,EAAe,EAAM,KAAgB,EAAM,KAAW,CAC1D,OACA,OAAQ,IAAU,EAAM,OAAS,EAAI,EAAkB,CACzD,EAAE,EACF,EAAO,OAAO,EAAO,EAAO,GAAG,CAAY,CAC7C,CACA,OAAO,EAAO,IAAK,GAAU,GAAG,EAAM,OAAO,EAAM,QAAQ,CAAC,CAAC,KAAK,EAAE,CACtE,CAEA,SAAS,EAAc,EAA8B,CACnD,IAAM,EAAsB,CAAC,EACzB,EAAQ,EACZ,IAAK,IAAI,EAAQ,EAAG,EAAQ,EAAQ,OAAQ,GAAS,EAAG,CACtD,IAAM,EAAY,EAAQ,GAC1B,GAAI,IAAc,MAAQ,IAAc;EAAM,SAC9C,IAAM,EAAS,IAAc,MAAQ,EAAQ,EAAQ,KAAO;EAAO;EAAS,EAC5E,EAAO,KAAK,CAAE,KAAM,EAAQ,MAAM,EAAO,CAAK,EAAG,QAAO,CAAC,EACrD,IAAW;IAAQ,GAAS,GAChC,EAAQ,EAAQ,CAClB,CAEA,OADA,EAAO,KAAK,CAAE,KAAM,EAAQ,MAAM,CAAK,EAAG,OAAQ,EAAG,CAAC,EAC/C,CACT,CAEA,SAAS,EAAiB,EAAkC,CAC1D,GAAI,IAAY,MAAQ,IAAY,GAAI,MAAO,CAAC,EAChD,IAAM,EAAa,EAAc,CAAO,EAClC,EAAU,EAAW,SAAS;CAAI,EAAI,EAAW,MAAM,EAAG,EAAE,EAAI,EACtE,OAAO,IAAY,GAAK,CAAC,EAAI,EAAQ,MAAM;CAAI,CACjD"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const e=require("./editTool.cjs");let t=require("@agimon-ai/doompi-extension-contracts/cordis-host"),n=require("@agimon-ai/doompi-extension-contracts/tool-overrides");const r=`@agimon-ai/doompi-edit`;function i(t,i){t.inject([n.DOOM_TOOL_OVERRIDES_SERVICE],t=>{let a=(0,n.requireDoomToolOverrides)(t).claim({source:r,tools:[`edit`]});if(a.granted){try{e.registerHashlineEditTool(i)}catch(e){throw a.dispose(),e}return()=>a.dispose()}})}async function a(e){let n=await(0,t.connectDoomCordisHost)(e,r),i=n.root.plugin(o,{pi:e});try{await i}catch(e){try{await i.dispose()}finally{await n.dispose()}throw e}let a;e.on(`session_shutdown`,()=>a??=(async()=>{try{await i.dispose()}finally{await n.dispose()}})())}function o(e,t){i(e,t.pi)}exports.activateDoomPiEditExtension=a,exports.default=a,exports.installDoomPiEditRuntime=i;
|
|
2
|
-
//# sourceMappingURL=extension.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"extension.cjs","names":["DOOM_TOOL_OVERRIDES_SERVICE","requireDoomToolOverrides","connectDoomCordisHost"],"sources":["../../../src/adapters/pi/extension.ts"],"sourcesContent":["import { connectDoomCordisHost } from '@agimon-ai/doompi-extension-contracts/cordis-host';\nimport {\n DOOM_TOOL_OVERRIDES_SERVICE,\n requireDoomToolOverrides,\n} from '@agimon-ai/doompi-extension-contracts/tool-overrides';\nimport type { Context } from '@deepseek-ai/cordis';\nimport type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\nimport { registerHashlineEditTool } from './editTool.ts';\n\nconst PACKAGE_SOURCE = '@agimon-ai/doompi-edit';\n\n/** Install the hashline edit tool after claiming its shared Pi name. */\nexport function installDoomPiEditRuntime(cordis: Context, pi: ExtensionAPI): void {\n cordis.inject([DOOM_TOOL_OVERRIDES_SERVICE], (overridesContext) => {\n const registration = requireDoomToolOverrides(overridesContext).claim({\n source: PACKAGE_SOURCE,\n tools: ['edit'],\n });\n if (!registration.granted) return;\n try {\n registerHashlineEditTool(pi);\n } catch (error) {\n registration.dispose();\n throw error;\n }\n return () => registration.dispose();\n });\n}\n\n/** Connect the package's standard Pi entry to DoomPi's shared Cordis host. */\nexport async function activateDoomPiEditExtension(pi: ExtensionAPI): Promise<void> {\n const connection = await connectDoomCordisHost(pi, PACKAGE_SOURCE);\n const fiber = connection.root.plugin(doomPiEditPlugin, { pi });\n try {\n await fiber;\n } catch (error) {\n try {\n await fiber.dispose();\n } finally {\n await connection.dispose();\n }\n throw error;\n }\n\n let disposal: Promise<void> | undefined;\n pi.on(\n 'session_shutdown',\n () =>\n (disposal ??= (async () => {\n try {\n await fiber.dispose();\n } finally {\n await connection.dispose();\n }\n })()),\n );\n}\n\ninterface DoomPiEditPluginConfig {\n readonly pi: ExtensionAPI;\n}\n\nfunction doomPiEditPlugin(cordis: Context, config: DoomPiEditPluginConfig): void {\n installDoomPiEditRuntime(cordis, config.pi);\n}\n\nexport default activateDoomPiEditExtension;\n"],"mappings":"uKASA,MAAM,EAAiB,yBAGvB,SAAgB,EAAyB,EAAiB,EAAwB,CAChF,EAAO,OAAO,CAACA,EAAAA,2BAA2B,EAAI,GAAqB,CACjE,IAAM,GAAA,EAAeC,EAAAA,yBAAAA,CAAyB,CAAgB,CAAC,CAAC,MAAM,CACpE,OAAQ,EACR,MAAO,CAAC,MAAM,CAChB,CAAC,EACI,KAAa,QAClB,IAAI,CACF,EAAA,yBAAyB,CAAE,CAC7B,OAAS,EAAO,CAEd,MADA,EAAa,QAAQ,EACf,CACR,CACA,UAAa,EAAa,QAAQ,CADlC,CAEF,CAAC,CACH,CAGA,eAAsB,EAA4B,EAAiC,CACjF,IAAM,EAAa,MAAA,EAAMC,EAAAA,sBAAAA,CAAsB,EAAI,CAAc,EAC3D,EAAQ,EAAW,KAAK,OAAO,EAAkB,CAAE,IAAG,CAAC,EAC7D,GAAI,CACF,MAAM,CACR,OAAS,EAAO,CACd,GAAI,CACF,MAAM,EAAM,QAAQ,CACtB,QAAU,CACR,MAAM,EAAW,QAAQ,CAC3B,CACA,MAAM,CACR,CAEA,IAAI,EACJ,EAAG,GACD,uBAEG,KAAc,SAAY,CACzB,GAAI,CACF,MAAM,EAAM,QAAQ,CACtB,QAAU,CACR,MAAM,EAAW,QAAQ,CAC3B,CACF,EAAA,CAAG,CACP,CACF,CAMA,SAAS,EAAiB,EAAiB,EAAsC,CAC/E,EAAyB,EAAQ,EAAO,EAAE,CAC5C"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { Context } from "@deepseek-ai/cordis";
|
|
2
|
-
import { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
3
|
-
//#region src/adapters/pi/extension.d.ts
|
|
4
|
-
/** Install the hashline edit tool after claiming its shared Pi name. */
|
|
5
|
-
export declare function installDoomPiEditRuntime(cordis: Context, pi: ExtensionAPI): void;
|
|
6
|
-
/** Connect the package's standard Pi entry to DoomPi's shared Cordis host. */
|
|
7
|
-
export declare function activateDoomPiEditExtension(pi: ExtensionAPI): Promise<void>;
|
|
8
|
-
//#endregion
|
|
9
|
-
export { activateDoomPiEditExtension as default };
|
|
10
|
-
//# sourceMappingURL=extension.d.cts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"extension.d.cts","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"mappings":";;;;wBAYgB,yBAAyB,QAAQ,SAAS,IAAI;;wBAkBxC,4BAA4B,IAAI,eAAe"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
import { Context } from "@deepseek-ai/cordis";
|
|
3
|
-
//#region src/adapters/pi/extension.d.ts
|
|
4
|
-
/** Install the hashline edit tool after claiming its shared Pi name. */
|
|
5
|
-
export declare function installDoomPiEditRuntime(cordis: Context, pi: ExtensionAPI): void;
|
|
6
|
-
/** Connect the package's standard Pi entry to DoomPi's shared Cordis host. */
|
|
7
|
-
export declare function activateDoomPiEditExtension(pi: ExtensionAPI): Promise<void>;
|
|
8
|
-
//#endregion
|
|
9
|
-
export { activateDoomPiEditExtension as default };
|
|
10
|
-
//# sourceMappingURL=extension.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"extension.d.mts","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"mappings":";;;;wBAYgB,yBAAyB,QAAQ,SAAS,IAAI;;wBAkBxC,4BAA4B,IAAI,eAAe"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{registerHashlineEditTool as e}from"./editTool.mjs";import{connectDoomCordisHost as t}from"@agimon-ai/doompi-extension-contracts/cordis-host";import{DOOM_TOOL_OVERRIDES_SERVICE as n,requireDoomToolOverrides as r}from"@agimon-ai/doompi-extension-contracts/tool-overrides";const i=`@agimon-ai/doompi-edit`;function a(t,a){t.inject([n],t=>{let n=r(t).claim({source:i,tools:[`edit`]});if(n.granted){try{e(a)}catch(e){throw n.dispose(),e}return()=>n.dispose()}})}async function o(e){let n=await t(e,i),r=n.root.plugin(s,{pi:e});try{await r}catch(e){try{await r.dispose()}finally{await n.dispose()}throw e}let a;e.on(`session_shutdown`,()=>a??=(async()=>{try{await r.dispose()}finally{await n.dispose()}})())}function s(e,t){a(e,t.pi)}export{o as activateDoomPiEditExtension,o as default,a as installDoomPiEditRuntime};
|
|
2
|
-
//# sourceMappingURL=extension.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"extension.mjs","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"sourcesContent":["import { connectDoomCordisHost } from '@agimon-ai/doompi-extension-contracts/cordis-host';\nimport {\n DOOM_TOOL_OVERRIDES_SERVICE,\n requireDoomToolOverrides,\n} from '@agimon-ai/doompi-extension-contracts/tool-overrides';\nimport type { Context } from '@deepseek-ai/cordis';\nimport type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\nimport { registerHashlineEditTool } from './editTool.ts';\n\nconst PACKAGE_SOURCE = '@agimon-ai/doompi-edit';\n\n/** Install the hashline edit tool after claiming its shared Pi name. */\nexport function installDoomPiEditRuntime(cordis: Context, pi: ExtensionAPI): void {\n cordis.inject([DOOM_TOOL_OVERRIDES_SERVICE], (overridesContext) => {\n const registration = requireDoomToolOverrides(overridesContext).claim({\n source: PACKAGE_SOURCE,\n tools: ['edit'],\n });\n if (!registration.granted) return;\n try {\n registerHashlineEditTool(pi);\n } catch (error) {\n registration.dispose();\n throw error;\n }\n return () => registration.dispose();\n });\n}\n\n/** Connect the package's standard Pi entry to DoomPi's shared Cordis host. */\nexport async function activateDoomPiEditExtension(pi: ExtensionAPI): Promise<void> {\n const connection = await connectDoomCordisHost(pi, PACKAGE_SOURCE);\n const fiber = connection.root.plugin(doomPiEditPlugin, { pi });\n try {\n await fiber;\n } catch (error) {\n try {\n await fiber.dispose();\n } finally {\n await connection.dispose();\n }\n throw error;\n }\n\n let disposal: Promise<void> | undefined;\n pi.on(\n 'session_shutdown',\n () =>\n (disposal ??= (async () => {\n try {\n await fiber.dispose();\n } finally {\n await connection.dispose();\n }\n })()),\n );\n}\n\ninterface DoomPiEditPluginConfig {\n readonly pi: ExtensionAPI;\n}\n\nfunction doomPiEditPlugin(cordis: Context, config: DoomPiEditPluginConfig): void {\n installDoomPiEditRuntime(cordis, config.pi);\n}\n\nexport default activateDoomPiEditExtension;\n"],"mappings":"qRASA,MAAM,EAAiB,yBAGvB,SAAgB,EAAyB,EAAiB,EAAwB,CAChF,EAAO,OAAO,CAAC,CAA2B,EAAI,GAAqB,CACjE,IAAM,EAAe,EAAyB,CAAgB,CAAC,CAAC,MAAM,CACpE,OAAQ,EACR,MAAO,CAAC,MAAM,CAChB,CAAC,EACI,KAAa,QAClB,IAAI,CACF,EAAyB,CAAE,CAC7B,OAAS,EAAO,CAEd,MADA,EAAa,QAAQ,EACf,CACR,CACA,UAAa,EAAa,QAAQ,CADlC,CAEF,CAAC,CACH,CAGA,eAAsB,EAA4B,EAAiC,CACjF,IAAM,EAAa,MAAM,EAAsB,EAAI,CAAc,EAC3D,EAAQ,EAAW,KAAK,OAAO,EAAkB,CAAE,IAAG,CAAC,EAC7D,GAAI,CACF,MAAM,CACR,OAAS,EAAO,CACd,GAAI,CACF,MAAM,EAAM,QAAQ,CACtB,QAAU,CACR,MAAM,EAAW,QAAQ,CAC3B,CACA,MAAM,CACR,CAEA,IAAI,EACJ,EAAG,GACD,uBAEG,KAAc,SAAY,CACzB,GAAI,CACF,MAAM,EAAM,QAAQ,CACtB,QAAU,CACR,MAAM,EAAW,QAAQ,CAC3B,CACF,EAAA,CAAG,CACP,CACF,CAMA,SAAS,EAAiB,EAAiB,EAAsC,CAC/E,EAAyB,EAAQ,EAAO,EAAE,CAC5C"}
|
package/src/exports/webClient.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { webPlugin } from '../web/index.ts';
|
package/src/web/index.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { defineWebPlugin } from '@agimon-ai/doompi-web-contracts';
|
|
2
|
-
import { EditToolMessage } from './components/EditToolMessage.tsx';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* This package's cockpit presence: the edit tool's timeline card, the web
|
|
6
|
-
* half of the TUI's renderCall and renderResult for hashline edits.
|
|
7
|
-
*/
|
|
8
|
-
export const webPlugin = defineWebPlugin({
|
|
9
|
-
id: 'edit',
|
|
10
|
-
toolRenderers: [{ tools: ['edit'], message: EditToolMessage }],
|
|
11
|
-
});
|