@agimon-ai/po-file-edit 0.0.0-alpha.2 → 0.0.0-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -18,7 +18,7 @@ tree comparison. See [What this cannot see](#what-this-cannot-see) for gaps in t
18
18
 
19
19
  ## Install
20
20
 
21
- `po init` and `dpi init` include File Edit in `default.packages` in `.po/modes.yaml`.
21
+ `po init` include File Edit in `default.packages` in `.po/modes.yaml`.
22
22
  Remove it or move it to a named layer to change which major modes load it.
23
23
 
24
24
  | Entry | Purpose |
@@ -62,7 +62,7 @@ and keeps it, content-addressed, beside the session timeline; both go when the s
62
62
 
63
63
  The timeline contains file paths, and the snapshot store holds copies of the file content the
64
64
  session changed. That content can be sensitive. Both live under the Pi agent directory,
65
- `$PI_CODING_AGENT_DIR` or `~/.po/agent/doom-file-edit`, never inside the working tree, and should be
65
+ `$PI_CODING_AGENT_DIR` or `~/.po/agent/po-file-edit`, never inside the working tree, and should be
66
66
  protected with the same access controls as Pi session data.
67
67
 
68
68
  A parent session removes its own timeline and snapshots on final disposal. Child sessions share the parent timeline and do not clear it. Activity selection stops retain review data for reactivation. A session that is killed cannot, so
@@ -141,7 +141,7 @@ const apiContracts = (0, _agimon_ai_po_core_apiContracts.defineApiContract)({
141
141
  sockets: ["global", "workspace"].map((scope) => ({
142
142
  id: "files.channel",
143
143
  scope,
144
- service: "po.hub.v1",
144
+ service: "po.hub",
145
145
  member: "file_edits",
146
146
  kind: "channel",
147
147
  direction: "server-to-client",
@@ -1 +1 @@
1
- {"version":3,"file":"apiContracts.cjs","names":["Type","defineApiContract","jsonApiResponses"],"sources":["../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract, jsonApiResponses } from '@agimon-ai/po-core/apiContracts';\nimport { Type } from 'typebox';\n\nconst S = Type.String();\nconst N = Type.Number();\nconst B = Type.Boolean();\nconst O = Type.Optional;\nconst literals = <T extends string>(values: T[]) => Type.Union(values.map((value) => Type.Literal(value)));\nconst Tool = literals(['edit', 'write', 'bash', 'user']);\nconst Hunk = Type.Object({\n start: N,\n rows: Type.Array(Type.Object({ marker: literals(['+', '-', ' ']), line: N, content: S })),\n});\nconst Diff = { additions: N, removals: N, hunks: O(Type.Array(Hunk)), note: O(S) };\nconst Working = Type.Object({ content: S, hash: S, unavailable: B, reason: O(S) });\nexport const FileDetailSchema = Type.Object({\n path: S,\n relPath: S,\n versions: Type.Array(Type.Object({ index: N, tool: Tool, at: N, origin: literals(['tool', 'scan']), ...Diff })),\n cumulative: Type.Object(Diff),\n working: Working,\n});\nexport const FilesPayloadSchema = Type.Object({\n items: Type.Array(Type.Object({ path: S, relPath: S, tool: Tool, at: N, count: N, diffable: B })),\n});\nconst query = [{ name: 'path', in: 'query' as const, required: true, schema: Type.String({ minLength: 1 }) }];\nexport const apiContracts = defineApiContract({\n version: 1,\n dynamic: [],\n http: [\n {\n id: 'files.detail',\n scope: 'session',\n basePath: 'file-edits',\n path: '/detail',\n method: 'GET',\n authentication: 'owner',\n description: 'Read recorded changes and current file content.',\n parameters: query,\n responses: jsonApiResponses(FileDetailSchema),\n },\n {\n id: 'files.preview',\n scope: 'session',\n basePath: 'file-edits',\n path: '/preview',\n method: 'GET',\n authentication: 'owner',\n description: 'Read a file contained in the session directory.',\n parameters: query,\n responses: jsonApiResponses(Type.Object({ path: S, relPath: S, working: Working })),\n },\n {\n id: 'files.save',\n scope: 'session',\n basePath: 'file-edits',\n path: '/content',\n method: 'PUT',\n authentication: 'owner',\n description: 'Save a recorded file if its hash still matches.',\n body: {\n required: true,\n contentType: 'application/json',\n schema: Type.Object({ path: S, expectedHash: S, content: S }),\n },\n responses: jsonApiResponses(Type.Object({ hash: S })),\n },\n {\n id: 'files.delete',\n scope: 'session',\n basePath: 'file-edits',\n path: '/content',\n method: 'DELETE',\n authentication: 'owner',\n description: 'Delete a recorded file.',\n parameters: query,\n responses: {\n '204': { description: 'File deleted or already absent.' },\n '404': { description: 'Unrecorded file.', schema: Type.Object({ error: S }) },\n '409': { description: 'Deletion failed.', schema: Type.Object({ error: S }) },\n },\n },\n ],\n sockets: (['global', 'workspace'] as const).map((scope) => ({\n id: 'files.channel',\n scope,\n service: 'po.hub.v1',\n member: 'file_edits',\n kind: 'channel',\n direction: 'server-to-client',\n description: 'File edits channel payload in the hub frame payload property.',\n input: FilesPayloadSchema,\n })),\n});\nexport default apiContracts;\n"],"mappings":"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"}
1
+ {"version":3,"file":"apiContracts.cjs","names":["Type","defineApiContract","jsonApiResponses"],"sources":["../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract, jsonApiResponses } from '@agimon-ai/po-core/apiContracts';\nimport { Type } from 'typebox';\n\nconst S = Type.String();\nconst N = Type.Number();\nconst B = Type.Boolean();\nconst O = Type.Optional;\nconst literals = <T extends string>(values: T[]) => Type.Union(values.map((value) => Type.Literal(value)));\nconst Tool = literals(['edit', 'write', 'bash', 'user']);\nconst Hunk = Type.Object({\n start: N,\n rows: Type.Array(Type.Object({ marker: literals(['+', '-', ' ']), line: N, content: S })),\n});\nconst Diff = { additions: N, removals: N, hunks: O(Type.Array(Hunk)), note: O(S) };\nconst Working = Type.Object({ content: S, hash: S, unavailable: B, reason: O(S) });\nexport const FileDetailSchema = Type.Object({\n path: S,\n relPath: S,\n versions: Type.Array(Type.Object({ index: N, tool: Tool, at: N, origin: literals(['tool', 'scan']), ...Diff })),\n cumulative: Type.Object(Diff),\n working: Working,\n});\nexport const FilesPayloadSchema = Type.Object({\n items: Type.Array(Type.Object({ path: S, relPath: S, tool: Tool, at: N, count: N, diffable: B })),\n});\nconst query = [{ name: 'path', in: 'query' as const, required: true, schema: Type.String({ minLength: 1 }) }];\nexport const apiContracts = defineApiContract({\n version: 1,\n dynamic: [],\n http: [\n {\n id: 'files.detail',\n scope: 'session',\n basePath: 'file-edits',\n path: '/detail',\n method: 'GET',\n authentication: 'owner',\n description: 'Read recorded changes and current file content.',\n parameters: query,\n responses: jsonApiResponses(FileDetailSchema),\n },\n {\n id: 'files.preview',\n scope: 'session',\n basePath: 'file-edits',\n path: '/preview',\n method: 'GET',\n authentication: 'owner',\n description: 'Read a file contained in the session directory.',\n parameters: query,\n responses: jsonApiResponses(Type.Object({ path: S, relPath: S, working: Working })),\n },\n {\n id: 'files.save',\n scope: 'session',\n basePath: 'file-edits',\n path: '/content',\n method: 'PUT',\n authentication: 'owner',\n description: 'Save a recorded file if its hash still matches.',\n body: {\n required: true,\n contentType: 'application/json',\n schema: Type.Object({ path: S, expectedHash: S, content: S }),\n },\n responses: jsonApiResponses(Type.Object({ hash: S })),\n },\n {\n id: 'files.delete',\n scope: 'session',\n basePath: 'file-edits',\n path: '/content',\n method: 'DELETE',\n authentication: 'owner',\n description: 'Delete a recorded file.',\n parameters: query,\n responses: {\n '204': { description: 'File deleted or already absent.' },\n '404': { description: 'Unrecorded file.', schema: Type.Object({ error: S }) },\n '409': { description: 'Deletion failed.', schema: Type.Object({ error: S }) },\n },\n },\n ],\n sockets: (['global', 'workspace'] as const).map((scope) => ({\n id: 'files.channel',\n scope,\n service: 'po.hub',\n member: 'file_edits',\n kind: 'channel',\n direction: 'server-to-client',\n description: 'File edits channel payload in the hub frame payload property.',\n input: FilesPayloadSchema,\n })),\n});\nexport default apiContracts;\n"],"mappings":"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"}
@@ -137,7 +137,7 @@ const apiContracts = defineApiContract({
137
137
  sockets: ["global", "workspace"].map((scope) => ({
138
138
  id: "files.channel",
139
139
  scope,
140
- service: "po.hub.v1",
140
+ service: "po.hub",
141
141
  member: "file_edits",
142
142
  kind: "channel",
143
143
  direction: "server-to-client",
@@ -1 +1 @@
1
- {"version":3,"file":"apiContracts.mjs","names":[],"sources":["../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract, jsonApiResponses } from '@agimon-ai/po-core/apiContracts';\nimport { Type } from 'typebox';\n\nconst S = Type.String();\nconst N = Type.Number();\nconst B = Type.Boolean();\nconst O = Type.Optional;\nconst literals = <T extends string>(values: T[]) => Type.Union(values.map((value) => Type.Literal(value)));\nconst Tool = literals(['edit', 'write', 'bash', 'user']);\nconst Hunk = Type.Object({\n start: N,\n rows: Type.Array(Type.Object({ marker: literals(['+', '-', ' ']), line: N, content: S })),\n});\nconst Diff = { additions: N, removals: N, hunks: O(Type.Array(Hunk)), note: O(S) };\nconst Working = Type.Object({ content: S, hash: S, unavailable: B, reason: O(S) });\nexport const FileDetailSchema = Type.Object({\n path: S,\n relPath: S,\n versions: Type.Array(Type.Object({ index: N, tool: Tool, at: N, origin: literals(['tool', 'scan']), ...Diff })),\n cumulative: Type.Object(Diff),\n working: Working,\n});\nexport const FilesPayloadSchema = Type.Object({\n items: Type.Array(Type.Object({ path: S, relPath: S, tool: Tool, at: N, count: N, diffable: B })),\n});\nconst query = [{ name: 'path', in: 'query' as const, required: true, schema: Type.String({ minLength: 1 }) }];\nexport const apiContracts = defineApiContract({\n version: 1,\n dynamic: [],\n http: [\n {\n id: 'files.detail',\n scope: 'session',\n basePath: 'file-edits',\n path: '/detail',\n method: 'GET',\n authentication: 'owner',\n description: 'Read recorded changes and current file content.',\n parameters: query,\n responses: jsonApiResponses(FileDetailSchema),\n },\n {\n id: 'files.preview',\n scope: 'session',\n basePath: 'file-edits',\n path: '/preview',\n method: 'GET',\n authentication: 'owner',\n description: 'Read a file contained in the session directory.',\n parameters: query,\n responses: jsonApiResponses(Type.Object({ path: S, relPath: S, working: Working })),\n },\n {\n id: 'files.save',\n scope: 'session',\n basePath: 'file-edits',\n path: '/content',\n method: 'PUT',\n authentication: 'owner',\n description: 'Save a recorded file if its hash still matches.',\n body: {\n required: true,\n contentType: 'application/json',\n schema: Type.Object({ path: S, expectedHash: S, content: S }),\n },\n responses: jsonApiResponses(Type.Object({ hash: S })),\n },\n {\n id: 'files.delete',\n scope: 'session',\n basePath: 'file-edits',\n path: '/content',\n method: 'DELETE',\n authentication: 'owner',\n description: 'Delete a recorded file.',\n parameters: query,\n responses: {\n '204': { description: 'File deleted or already absent.' },\n '404': { description: 'Unrecorded file.', schema: Type.Object({ error: S }) },\n '409': { description: 'Deletion failed.', schema: Type.Object({ error: S }) },\n },\n },\n ],\n sockets: (['global', 'workspace'] as const).map((scope) => ({\n id: 'files.channel',\n scope,\n service: 'po.hub.v1',\n member: 'file_edits',\n kind: 'channel',\n direction: 'server-to-client',\n description: 'File edits channel payload in the hub frame payload property.',\n input: FilesPayloadSchema,\n })),\n});\nexport default apiContracts;\n"],"mappings":"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"}
1
+ {"version":3,"file":"apiContracts.mjs","names":[],"sources":["../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract, jsonApiResponses } from '@agimon-ai/po-core/apiContracts';\nimport { Type } from 'typebox';\n\nconst S = Type.String();\nconst N = Type.Number();\nconst B = Type.Boolean();\nconst O = Type.Optional;\nconst literals = <T extends string>(values: T[]) => Type.Union(values.map((value) => Type.Literal(value)));\nconst Tool = literals(['edit', 'write', 'bash', 'user']);\nconst Hunk = Type.Object({\n start: N,\n rows: Type.Array(Type.Object({ marker: literals(['+', '-', ' ']), line: N, content: S })),\n});\nconst Diff = { additions: N, removals: N, hunks: O(Type.Array(Hunk)), note: O(S) };\nconst Working = Type.Object({ content: S, hash: S, unavailable: B, reason: O(S) });\nexport const FileDetailSchema = Type.Object({\n path: S,\n relPath: S,\n versions: Type.Array(Type.Object({ index: N, tool: Tool, at: N, origin: literals(['tool', 'scan']), ...Diff })),\n cumulative: Type.Object(Diff),\n working: Working,\n});\nexport const FilesPayloadSchema = Type.Object({\n items: Type.Array(Type.Object({ path: S, relPath: S, tool: Tool, at: N, count: N, diffable: B })),\n});\nconst query = [{ name: 'path', in: 'query' as const, required: true, schema: Type.String({ minLength: 1 }) }];\nexport const apiContracts = defineApiContract({\n version: 1,\n dynamic: [],\n http: [\n {\n id: 'files.detail',\n scope: 'session',\n basePath: 'file-edits',\n path: '/detail',\n method: 'GET',\n authentication: 'owner',\n description: 'Read recorded changes and current file content.',\n parameters: query,\n responses: jsonApiResponses(FileDetailSchema),\n },\n {\n id: 'files.preview',\n scope: 'session',\n basePath: 'file-edits',\n path: '/preview',\n method: 'GET',\n authentication: 'owner',\n description: 'Read a file contained in the session directory.',\n parameters: query,\n responses: jsonApiResponses(Type.Object({ path: S, relPath: S, working: Working })),\n },\n {\n id: 'files.save',\n scope: 'session',\n basePath: 'file-edits',\n path: '/content',\n method: 'PUT',\n authentication: 'owner',\n description: 'Save a recorded file if its hash still matches.',\n body: {\n required: true,\n contentType: 'application/json',\n schema: Type.Object({ path: S, expectedHash: S, content: S }),\n },\n responses: jsonApiResponses(Type.Object({ hash: S })),\n },\n {\n id: 'files.delete',\n scope: 'session',\n basePath: 'file-edits',\n path: '/content',\n method: 'DELETE',\n authentication: 'owner',\n description: 'Delete a recorded file.',\n parameters: query,\n responses: {\n '204': { description: 'File deleted or already absent.' },\n '404': { description: 'Unrecorded file.', schema: Type.Object({ error: S }) },\n '409': { description: 'Deletion failed.', schema: Type.Object({ error: S }) },\n },\n },\n ],\n sockets: (['global', 'workspace'] as const).map((scope) => ({\n id: 'files.channel',\n scope,\n service: 'po.hub',\n member: 'file_edits',\n kind: 'channel',\n direction: 'server-to-client',\n description: 'File edits channel payload in the hub frame payload property.',\n input: FilesPayloadSchema,\n })),\n});\nexport default apiContracts;\n"],"mappings":"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"}