@schilderlabs/pitown-core 0.2.6 → 0.2.7

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/dist/index.mjs CHANGED
@@ -1,11 +1,8 @@
1
- import { C as appendJsonl, S as writeAgentState, _ as getLatestAgentSession, a as readTaskRecord, b as readAgentMessages, c as appendAgentMessage, d as getAgentDir, f as getAgentMailboxPath, g as getAgentsDir, h as getAgentStatePath, i as listTaskRecords, l as createAgentSessionRecord, m as getAgentSessionsDir, n as getTaskPath, o as updateTaskRecordStatus, p as getAgentSessionPath, r as getTasksDir, s as writeTaskRecord, t as createTaskRecord, u as createAgentState, v as getSessionIdFromPath, w as readJsonl, x as readAgentState, y as listAgentStates } from "./tasks-BfQm-7-O.mjs";
2
- import { createRequire } from "node:module";
1
+ import { A as getLatestAgentSession, C as createAgentState, D as getAgentSessionsDir, E as getAgentSessionPath, F as writeAgentState, I as appendJsonl, L as readJsonl, M as listAgentStates, N as readAgentMessages, O as getAgentStatePath, P as readAgentState, S as createAgentSessionRecord, T as getAgentMailboxPath, _ as assertCommandAvailable, a as resolveAgentSession, b as runCommandSync, c as spawnAgentRun, d as getTaskPath, f as getTasksDir, g as writeTaskRecord, h as updateTaskRecordStatus, i as queueAgentMessage, j as getSessionIdFromPath, k as getAgentsDir, l as updateAgentStatus, m as readTaskRecord, n as delegateTask, o as resumeAgentTurnDetached, p as listTaskRecords, r as notifyTaskDelegator, s as runAgentTurn, t as createRolePrompt, u as createTaskRecord, v as assertSuccess, w as getAgentDir, x as appendAgentMessage, y as runCommandInteractive } from "./orchestration-D6XeSl8s.mjs";
3
2
  import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
4
3
  import { basename, join, resolve } from "node:path";
5
4
  import { homedir, hostname } from "node:os";
6
5
  import { createHash, randomUUID } from "node:crypto";
7
- import { spawn, spawnSync } from "node:child_process";
8
- import { fileURLToPath } from "node:url";
9
6
 
10
7
  //#region src/lease.ts
11
8
  function sanitize$1(value) {
@@ -116,44 +113,6 @@ function createPiAuthHelpMessage() {
116
113
  return "Pi appears to be installed but not authenticated or configured. Verify Pi works first: pi -p \"hello\". Either set an API key or run `pi` and use `/login`.";
117
114
  }
118
115
 
119
- //#endregion
120
- //#region src/shell.ts
121
- function runCommandSync(command, args, options) {
122
- const result = spawnSync(command, args, {
123
- cwd: options?.cwd,
124
- env: options?.env,
125
- encoding: "utf-8"
126
- });
127
- const errorText = result.error instanceof Error ? `${result.error.message}
128
- ` : "";
129
- return {
130
- stdout: result.stdout ?? "",
131
- stderr: `${errorText}${result.stderr ?? ""}`,
132
- exitCode: result.status ?? 1
133
- };
134
- }
135
- function assertCommandAvailable(command) {
136
- const result = spawnSync(command, ["--help"], {
137
- encoding: "utf-8",
138
- stdio: "ignore"
139
- });
140
- if (result.error instanceof Error) throw new Error(result.error.message);
141
- }
142
- function runCommandInteractive(command, args, options) {
143
- const result = spawnSync(command, args, {
144
- cwd: options?.cwd,
145
- env: options?.env,
146
- stdio: "inherit"
147
- });
148
- if (result.error instanceof Error) throw new Error(result.error.message);
149
- return result.status ?? 1;
150
- }
151
- function assertSuccess(result, context) {
152
- if (result.exitCode === 0) return;
153
- const details = [result.stdout.trim(), result.stderr.trim()].filter(Boolean).join("\n");
154
- throw new Error(`${context} failed${details ? `\n${details}` : ""}`);
155
- }
156
-
157
116
  //#endregion
158
117
  //#region src/repo.ts
159
118
  function gitResult(cwd, args) {
@@ -208,7 +167,7 @@ function createRepoSlug(repoId, repoRoot) {
208
167
  function createRunId() {
209
168
  return `run-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}`;
210
169
  }
211
- function createPiInvocationArgs$1(input) {
170
+ function createPiInvocationArgs(input) {
212
171
  const args = [];
213
172
  if (input.extensionPath) args.push("--extension", input.extensionPath);
214
173
  if (input.appendedSystemPrompt) args.push("--append-system-prompt", input.appendedSystemPrompt);
@@ -388,7 +347,7 @@ function runController(options) {
388
347
  status: "running",
389
348
  lastMessage: goal ? `Mayor working on: ${goal}` : "Mayor working"
390
349
  }));
391
- const piResult = runCommandSync(piCommand, createPiInvocationArgs$1({
350
+ const piResult = runCommandSync(piCommand, createPiInvocationArgs({
392
351
  sessionDir: mayorState.session.sessionPath === null ? mayorSessionDir : null,
393
352
  sessionPath: mayorState.session.sessionPath,
394
353
  prompt,
@@ -793,318 +752,6 @@ function runLoop(options) {
793
752
  return loopResult;
794
753
  }
795
754
 
796
- //#endregion
797
- //#region src/orchestration.ts
798
- function createPiInvocationArgs(input) {
799
- const args = [];
800
- if (input.extensionPath) args.push("--extension", input.extensionPath);
801
- if (input.appendedSystemPrompt) args.push("--append-system-prompt", input.appendedSystemPrompt);
802
- if (input.sessionPath) args.push("--session", input.sessionPath);
803
- else if (input.sessionDir) args.push("--session-dir", input.sessionDir);
804
- else throw new Error("Pi invocation requires a session path or session directory");
805
- if (input.prompt) args.push("-p", input.prompt);
806
- return args;
807
- }
808
- function createDetachedRunnerInvocation(encodedPayload) {
809
- if (fileURLToPath(import.meta.url).endsWith(".ts")) {
810
- const require = createRequire(import.meta.url);
811
- return {
812
- command: process.execPath,
813
- args: [
814
- "--import",
815
- require.resolve("tsx"),
816
- fileURLToPath(new URL("./agent-runner.ts", import.meta.url)),
817
- encodedPayload
818
- ]
819
- };
820
- }
821
- return {
822
- command: process.execPath,
823
- args: [fileURLToPath(new URL("./agent-runner.mjs", import.meta.url)), encodedPayload]
824
- };
825
- }
826
- function createRolePrompt(input) {
827
- const task = input.task ?? "pick the next bounded task from the current repo context";
828
- switch (input.role) {
829
- case "mayor": return [
830
- "You are the Pi Town mayor.",
831
- "You coordinate work for this repository and act as the primary human-facing agent.",
832
- "",
833
- `Repository: ${input.repoRoot}`,
834
- `Task: ${task}`,
835
- "Keep updates concise, choose bounded next steps, and leave a durable artifact trail."
836
- ].join("\n");
837
- case "reviewer": return [
838
- "You are the Pi Town reviewer.",
839
- "You review work for correctness, safety, and completeness.",
840
- "",
841
- `Repository: ${input.repoRoot}`,
842
- `Task: ${task}`,
843
- "Focus on validation confidence, regressions, and whether the output is ready for a human handoff."
844
- ].join("\n");
845
- case "docs-keeper": return [
846
- "You are the Pi Town docs keeper.",
847
- "You summarize outcomes, blockers, and continuity in compact factual language.",
848
- "",
849
- `Repository: ${input.repoRoot}`,
850
- `Task: ${task}`,
851
- "Keep the output concise and useful for the next run or human review."
852
- ].join("\n");
853
- default: return [
854
- "You are the Pi Town worker.",
855
- "You implement one bounded task at a time.",
856
- "",
857
- `Repository: ${input.repoRoot}`,
858
- `Task: ${task}`,
859
- "Keep scope tight, prefer explicit validations, and summarize what changed and what still needs follow-up."
860
- ].join("\n");
861
- }
862
- }
863
- function resolveAgentSession(agentId, artifactsDir) {
864
- const state = readAgentState(artifactsDir, agentId);
865
- if (state === null) throw new Error(`Unknown agent: ${agentId}`);
866
- const latestSession = getLatestAgentSession(artifactsDir, agentId);
867
- const sessionPath = state.session.sessionPath ?? latestSession.sessionPath;
868
- const sessionId = state.session.sessionId ?? latestSession.sessionId;
869
- const sessionDir = state.session.sessionDir ?? latestSession.sessionDir ?? getAgentSessionsDir(artifactsDir, agentId);
870
- if (sessionPath === null) throw new Error(`Agent ${agentId} does not have a persisted Pi session yet.`);
871
- return {
872
- state,
873
- session: createAgentSessionRecord({
874
- sessionDir,
875
- sessionId,
876
- sessionPath,
877
- processId: state.session.processId,
878
- lastAttachedAt: (/* @__PURE__ */ new Date()).toISOString()
879
- })
880
- };
881
- }
882
- function queueAgentMessage(input) {
883
- const state = readAgentState(input.artifactsDir, input.agentId);
884
- if (state === null) throw new Error(`Unknown agent: ${input.agentId}`);
885
- appendAgentMessage({
886
- artifactsDir: input.artifactsDir,
887
- agentId: input.agentId,
888
- box: "inbox",
889
- from: input.from,
890
- body: input.body
891
- });
892
- writeAgentState(input.artifactsDir, createAgentState({
893
- ...state,
894
- status: state.status === "idle" ? "queued" : state.status,
895
- lastMessage: input.body,
896
- waitingOn: null,
897
- blocked: false,
898
- session: createAgentSessionRecord({
899
- sessionDir: state.session.sessionDir ?? getAgentSessionsDir(input.artifactsDir, input.agentId),
900
- sessionId: state.session.sessionId,
901
- sessionPath: state.session.sessionPath,
902
- processId: state.session.processId,
903
- lastAttachedAt: state.session.lastAttachedAt
904
- })
905
- }));
906
- }
907
- function updateAgentStatus(input) {
908
- const state = readAgentState(input.artifactsDir, input.agentId);
909
- if (state === null) throw new Error(`Unknown agent: ${input.agentId}`);
910
- if (state.taskId) {
911
- const taskStatus = input.status === "completed" ? "completed" : input.status === "blocked" || input.status === "failed" ? "blocked" : input.status === "stopped" ? "aborted" : input.status === "running" || input.status === "queued" ? "running" : null;
912
- if (taskStatus) updateTaskRecordStatus(input.artifactsDir, state.taskId, taskStatus);
913
- }
914
- writeAgentState(input.artifactsDir, createAgentState({
915
- ...state,
916
- status: input.status,
917
- lastMessage: input.lastMessage ?? state.lastMessage,
918
- waitingOn: input.waitingOn ?? state.waitingOn,
919
- blocked: input.blocked ?? state.blocked,
920
- session: state.session
921
- }));
922
- }
923
- function spawnAgentRun(options) {
924
- const sessionDir = getAgentSessionsDir(options.artifactsDir, options.agentId);
925
- if (readAgentState(options.artifactsDir, options.agentId) !== null) throw new Error(`Agent already exists: ${options.agentId}`);
926
- assertCommandAvailable("pi");
927
- const state = createAgentState({
928
- agentId: options.agentId,
929
- role: options.role,
930
- status: "queued",
931
- taskId: options.taskId ?? null,
932
- task: options.task,
933
- lastMessage: options.task ? `Spawned with task: ${options.task}` : `Spawned ${options.role} agent`,
934
- session: createAgentSessionRecord({ sessionDir })
935
- });
936
- writeAgentState(options.artifactsDir, state);
937
- if (options.task) appendAgentMessage({
938
- artifactsDir: options.artifactsDir,
939
- agentId: options.agentId,
940
- box: "inbox",
941
- from: "system",
942
- body: options.task
943
- });
944
- writeAgentState(options.artifactsDir, createAgentState({
945
- ...state,
946
- status: "running",
947
- lastMessage: options.task ? `Running ${options.role} task: ${options.task}` : `Running ${options.role} agent`
948
- }));
949
- const piArgs = createPiInvocationArgs({
950
- sessionDir,
951
- prompt: createRolePrompt({
952
- role: options.role,
953
- task: options.task,
954
- repoRoot: options.repoRoot
955
- }),
956
- appendedSystemPrompt: options.appendedSystemPrompt,
957
- extensionPath: options.extensionPath
958
- });
959
- const startedAt = (/* @__PURE__ */ new Date()).toISOString();
960
- const runner = createDetachedRunnerInvocation(Buffer.from(JSON.stringify({
961
- repoRoot: options.repoRoot,
962
- artifactsDir: options.artifactsDir,
963
- agentId: options.agentId,
964
- role: options.role,
965
- task: options.task,
966
- taskId: options.taskId ?? null,
967
- sessionDir,
968
- piArgs
969
- }), "utf-8").toString("base64url"));
970
- const child = spawn(runner.command, runner.args, {
971
- cwd: options.repoRoot,
972
- detached: true,
973
- env: process.env,
974
- stdio: "ignore"
975
- });
976
- child.unref();
977
- if (!child.pid) throw new Error(`Failed to launch detached ${options.role} run for ${options.agentId}`);
978
- writeFileSync(`${getAgentDir(options.artifactsDir, options.agentId)}/latest-invocation.json`, `${JSON.stringify({
979
- command: "pi",
980
- args: piArgs,
981
- exitCode: null,
982
- sessionDir,
983
- sessionPath: null,
984
- sessionId: null,
985
- processId: child.pid,
986
- startedAt
987
- }, null, 2)}\n`, "utf-8");
988
- return {
989
- launch: {
990
- processId: child.pid,
991
- startedAt
992
- },
993
- latestSession: createAgentSessionRecord({ sessionDir })
994
- };
995
- }
996
- function runAgentTurn(options) {
997
- assertCommandAvailable("pi");
998
- const resolved = resolveAgentSession(options.agentId, options.artifactsDir);
999
- const messageSource = options.from ?? "human";
1000
- writeAgentState(options.artifactsDir, createAgentState({
1001
- ...resolved.state,
1002
- status: "running",
1003
- lastMessage: `Responding to ${messageSource}: ${options.message}`,
1004
- waitingOn: null,
1005
- blocked: false,
1006
- session: resolved.session
1007
- }));
1008
- const piArgs = options.runtimeArgs && options.runtimeArgs.length > 0 ? options.runtimeArgs : createPiInvocationArgs({
1009
- sessionPath: resolved.session.sessionPath,
1010
- prompt: options.message
1011
- });
1012
- const piResult = runCommandSync("pi", piArgs, {
1013
- cwd: options.repoRoot,
1014
- env: process.env
1015
- });
1016
- const latestSession = getLatestAgentSession(options.artifactsDir, options.agentId);
1017
- const agentArtifactsDir = getAgentDir(options.artifactsDir, options.agentId);
1018
- writeFileSync(`${agentArtifactsDir}/latest-stdout.txt`, piResult.stdout, "utf-8");
1019
- writeFileSync(`${agentArtifactsDir}/latest-stderr.txt`, piResult.stderr, "utf-8");
1020
- writeFileSync(`${agentArtifactsDir}/latest-invocation.json`, `${JSON.stringify({
1021
- command: "pi",
1022
- args: piArgs,
1023
- exitCode: piResult.exitCode,
1024
- sessionDir: latestSession.sessionDir,
1025
- sessionPath: latestSession.sessionPath,
1026
- sessionId: latestSession.sessionId
1027
- }, null, 2)}\n`, "utf-8");
1028
- const completionMessage = piResult.stdout.trim() || (piResult.exitCode === 0 ? `${resolved.state.role} turn completed` : `${resolved.state.role} turn exited with code ${piResult.exitCode}`);
1029
- appendAgentMessage({
1030
- artifactsDir: options.artifactsDir,
1031
- agentId: options.agentId,
1032
- box: "outbox",
1033
- from: options.agentId,
1034
- body: completionMessage
1035
- });
1036
- writeAgentState(options.artifactsDir, createAgentState({
1037
- ...resolved.state,
1038
- status: piResult.exitCode === 0 ? "idle" : "blocked",
1039
- lastMessage: completionMessage,
1040
- waitingOn: piResult.exitCode === 0 ? null : "human-or-follow-up-run",
1041
- blocked: piResult.exitCode !== 0,
1042
- session: createAgentSessionRecord({
1043
- sessionDir: latestSession.sessionDir,
1044
- sessionId: latestSession.sessionId,
1045
- sessionPath: latestSession.sessionPath,
1046
- processId: null
1047
- })
1048
- }));
1049
- return {
1050
- piResult,
1051
- latestSession,
1052
- completionMessage
1053
- };
1054
- }
1055
- function delegateTask(options) {
1056
- if (readAgentState(options.artifactsDir, options.fromAgentId) === null) throw new Error(`Unknown delegating agent: ${options.fromAgentId}`);
1057
- const agentId = options.agentId ?? `${options.role}-${Date.now()}`;
1058
- const task = createTaskRecord({
1059
- taskId: `task-${Date.now()}`,
1060
- title: options.task,
1061
- status: "queued",
1062
- role: options.role,
1063
- assignedAgentId: agentId,
1064
- createdBy: options.fromAgentId
1065
- });
1066
- writeTaskRecord(options.artifactsDir, task);
1067
- appendAgentMessage({
1068
- artifactsDir: options.artifactsDir,
1069
- agentId: options.fromAgentId,
1070
- box: "outbox",
1071
- from: options.fromAgentId,
1072
- body: `Delegated ${task.taskId} to ${agentId}: ${options.task}`
1073
- });
1074
- const { launch, latestSession } = spawnAgentRun({
1075
- repoRoot: options.repoRoot,
1076
- artifactsDir: options.artifactsDir,
1077
- role: options.role,
1078
- agentId,
1079
- appendedSystemPrompt: options.appendedSystemPrompt,
1080
- extensionPath: options.extensionPath,
1081
- task: options.task,
1082
- taskId: task.taskId
1083
- });
1084
- appendAgentMessage({
1085
- artifactsDir: options.artifactsDir,
1086
- agentId,
1087
- box: "inbox",
1088
- from: options.fromAgentId,
1089
- body: `Delegated by ${options.fromAgentId} as ${task.taskId}: ${options.task}`
1090
- });
1091
- writeTaskRecord(options.artifactsDir, {
1092
- ...task,
1093
- status: "running",
1094
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1095
- });
1096
- return {
1097
- task: {
1098
- ...task,
1099
- status: "running",
1100
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1101
- },
1102
- agentId,
1103
- launch,
1104
- latestSession
1105
- };
1106
- }
1107
-
1108
755
  //#endregion
1109
756
  //#region src/stop.ts
1110
757
  const DEFAULT_GRACE_MS = 750;
@@ -1273,5 +920,5 @@ function stopManagedAgents(options) {
1273
920
  }
1274
921
 
1275
922
  //#endregion
1276
- export { acquireRepoLease, appendAgentMessage, appendJsonl, assertCommandAvailable, assertSuccess, computeAutonomousCompletionRate, computeContextCoverageScore, computeFeedbackToDemoCycleTime, computeInterruptRate, computeMeanTimeToCorrect, computeMetrics, createAgentSessionRecord, createAgentState, createInterruptRecord, createPiAuthHelpMessage, createRepoSlug, createRolePrompt, createTaskRecord, delegateTask, detectPiAuthFailure, evaluateStopCondition, getAgentDir, getAgentMailboxPath, getAgentSessionPath, getAgentSessionsDir, getAgentStatePath, getAgentsDir, getCurrentBranch, getLatestAgentSession, getRepoIdentity, getRepoRoot, getSessionIdFromPath, getTaskPath, getTasksDir, isGitRepo, listAgentStates, listRepoLeases, listTaskRecords, queueAgentMessage, readAgentMessages, readAgentState, readJsonl, readTaskRecord, resolveAgentSession, resolveInterrupt, runAgentTurn, runCommandInteractive, runCommandSync, runController, runLoop, snapshotBoard, spawnAgentRun, stopManagedAgents, stopRepoLeases, updateAgentStatus, updateTaskRecordStatus, writeAgentState, writeTaskRecord };
923
+ export { acquireRepoLease, appendAgentMessage, appendJsonl, assertCommandAvailable, assertSuccess, computeAutonomousCompletionRate, computeContextCoverageScore, computeFeedbackToDemoCycleTime, computeInterruptRate, computeMeanTimeToCorrect, computeMetrics, createAgentSessionRecord, createAgentState, createInterruptRecord, createPiAuthHelpMessage, createRepoSlug, createRolePrompt, createTaskRecord, delegateTask, detectPiAuthFailure, evaluateStopCondition, getAgentDir, getAgentMailboxPath, getAgentSessionPath, getAgentSessionsDir, getAgentStatePath, getAgentsDir, getCurrentBranch, getLatestAgentSession, getRepoIdentity, getRepoRoot, getSessionIdFromPath, getTaskPath, getTasksDir, isGitRepo, listAgentStates, listRepoLeases, listTaskRecords, notifyTaskDelegator, queueAgentMessage, readAgentMessages, readAgentState, readJsonl, readTaskRecord, resolveAgentSession, resolveInterrupt, resumeAgentTurnDetached, runAgentTurn, runCommandInteractive, runCommandSync, runController, runLoop, snapshotBoard, spawnAgentRun, stopManagedAgents, stopRepoLeases, updateAgentStatus, updateTaskRecordStatus, writeAgentState, writeTaskRecord };
1277
924
  //# sourceMappingURL=index.mjs.map