chatroom-cli 1.77.1 → 1.77.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/dist/index.js +330 -98
- package/dist/index.js.map +22 -20
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -77251,7 +77251,7 @@ function getDelegationBriefDisclosureBlock() {
|
|
|
77251
77251
|
return `${DELEGATION_BRIEF_DISCLOSURE_CHECKBOX}
|
|
77252
77252
|
${getDelegationBriefDisclosureComment()}`;
|
|
77253
77253
|
}
|
|
77254
|
-
var DELEGATION_BRIEF_DISCLOSURE_CHECKBOX = "- [ ] I confirm
|
|
77254
|
+
var DELEGATION_BRIEF_DISCLOSURE_CHECKBOX = "- [ ] I confirm the delegation brief is fully met: all (Required) files done, verified end-to-end, acceptance criteria pass";
|
|
77255
77255
|
|
|
77256
77256
|
// ../../services/backend/prompts/utils/file-reference-guidance.ts
|
|
77257
77257
|
function getFileReferenceGuidanceComment() {
|
|
@@ -77423,7 +77423,7 @@ ${getDelegationBriefIntro()}
|
|
|
77423
77423
|
<choices that greatly simplify the solution while preserving long-term maintainability — reuse existing abstractions, avoid unnecessary layers, leverage platform conventions>
|
|
77424
77424
|
|
|
77425
77425
|
## Files to implement (exhaustive, file-level)
|
|
77426
|
-
List **every** file in this slice. For each file, state the exact change and paste the code the builder should match (no guessing).
|
|
77426
|
+
List **every** file in this slice. Mark each file **(Required)** or **(Optional)** — all Required files must land before PR. For each file, state the exact change and paste the code the builder should match (no guessing).
|
|
77427
77427
|
${getFileReferenceGuidanceComment()}
|
|
77428
77428
|
|
|
77429
77429
|
### \`apps/webapp/src/path/to/file.ts\`
|
|
@@ -77458,6 +77458,7 @@ Cross-file types, interfaces, or patterns that apply beyond a single file. Omit
|
|
|
77458
77458
|
|
|
77459
77459
|
## Requirements (acceptance criteria)
|
|
77460
77460
|
- <verifiable outcome the builder can self-check>
|
|
77461
|
+
- Include at least one check that the feature is **verified end-to-end**. Unit tests alone are insufficient for new features.
|
|
77461
77462
|
|
|
77462
77463
|
## What to avoid
|
|
77463
77464
|
- <anti-patterns, recurring mistakes, or scope creep for this slice — be explicit>
|
|
@@ -77582,7 +77583,7 @@ ${getFileReferenceProofOfCompletionExample()}
|
|
|
77582
77583
|
<Omit if no backlog items were in scope.>
|
|
77583
77584
|
|
|
77584
77585
|
## Backlog Pending User Review Confirmation
|
|
77585
|
-
- [ ] I confirm that every backlog item implemented in this work has been moved to \`pending_user_review\` via \`chatroom backlog mark-for-review\`
|
|
77586
|
+
- [ ] I confirm that every backlog item implemented in this work has been moved to \`pending_user_review\` via \`chatroom backlog mark-for-review\` after the feature was verified end-to-end and a PR was raised for user review
|
|
77586
77587
|
- PR URL(s): <link to PR(s)>
|
|
77587
77588
|
<Omit this section if no backlog items apply.>
|
|
77588
77589
|
|
|
@@ -77610,9 +77611,6 @@ ${getUnresolvedDecisionsSectionBlock()}
|
|
|
77610
77611
|
|
|
77611
77612
|
## Notes
|
|
77612
77613
|
<anything the user should know — context, caveats, or observations not covered above. Omit if none.>
|
|
77613
|
-
|
|
77614
|
-
## Next steps
|
|
77615
|
-
<follow-up actions for the user or team. Omit if none.>
|
|
77616
77614
|
\`\`\``;
|
|
77617
77615
|
}
|
|
77618
77616
|
var init_planner_to_user = __esm(() => {
|
|
@@ -77687,7 +77685,7 @@ ${getFileReferenceProofOfCompletionExample()}
|
|
|
77687
77685
|
<Omit if no backlog items were in scope.>
|
|
77688
77686
|
|
|
77689
77687
|
## Backlog Pending User Review Confirmation
|
|
77690
|
-
- [ ] I confirm that every backlog item implemented in this work has been moved to \`pending_user_review\` via \`chatroom backlog mark-for-review\`
|
|
77688
|
+
- [ ] I confirm that every backlog item implemented in this work has been moved to \`pending_user_review\` via \`chatroom backlog mark-for-review\` after the feature was verified end-to-end and a PR was raised for user review
|
|
77691
77689
|
- PR URL(s): <link to PR(s)>
|
|
77692
77690
|
<Omit this section if no backlog items apply.>
|
|
77693
77691
|
|
|
@@ -77715,9 +77713,6 @@ ${getUnresolvedDecisionsSectionBlock()}
|
|
|
77715
77713
|
|
|
77716
77714
|
## Notes
|
|
77717
77715
|
<anything the user should know — context, caveats, or observations not covered above. Omit if none.>
|
|
77718
|
-
|
|
77719
|
-
## Next steps
|
|
77720
|
-
<follow-up actions for the user or team. Omit if none.>
|
|
77721
77716
|
\`\`\``;
|
|
77722
77717
|
}
|
|
77723
77718
|
var init_solo_to_user = __esm(() => {
|
|
@@ -78814,6 +78809,10 @@ ${getBuilderFlowMermaid(nativeIntegration, codeChangesTarget, questionTarget)}
|
|
|
78814
78809
|
- Follow established patterns and best practices from the codebase
|
|
78815
78810
|
- Handle edge cases and error scenarios
|
|
78816
78811
|
- Commit work with descriptive, atomic commit messages
|
|
78812
|
+
|
|
78813
|
+
**Completion gates (before PR or handoff):**
|
|
78814
|
+
- All **(Required)** files done; **verified end-to-end** (user-facing entry point works: CLI command runnable, API reachable, or UI action functional)
|
|
78815
|
+
- If blocked → ## Blockers / questions to planner. No PR or \`mark-for-review\` until gates pass — unless the user explicitly requested a draft or incremental PR
|
|
78817
78816
|
`;
|
|
78818
78817
|
}
|
|
78819
78818
|
var init_builder = () => {};
|
|
@@ -78885,18 +78884,21 @@ flowchart TD
|
|
|
78885
78884
|
- **Spell out what to avoid** — anti-patterns and recurring mistakes you have seen from builders on similar work (scope creep, wrong abstractions, forbidden refactors).
|
|
78886
78885
|
- **One slice ≈ one focused review surface.** If you can't imagine reviewing it in one sitting, split it.
|
|
78887
78886
|
- **Order by dependency**, not by team convention. A slice should be runnable/testable when its dependencies are done.
|
|
78887
|
+
- **A slice is shippable only when verified end-to-end** — infra/helper files alone are not a complete slice.
|
|
78888
78888
|
- **Skip phases that don't apply** (e.g., no frontend for a backend-only change, no schema for a pure refactor).
|
|
78889
78889
|
|
|
78890
78890
|
**Code review:** For code-producing work, review before delivering. Activate the review framework with: ${cmd("skill activate code-review")}.
|
|
78891
78891
|
|
|
78892
78892
|
**Backlog items:** When the task originates from a backlog item, activate the backlog skill: ${cmd("skill activate backlog")}.
|
|
78893
78893
|
|
|
78894
|
-
**If stuck:** After 2 failed rework attempts →
|
|
78894
|
+
**If stuck:** After 2 failed rework attempts → replan or hand back to planner as blocked. No partial PR, \`mark-for-review\`, or user delivery.
|
|
78895
78895
|
|
|
78896
78896
|
**Review loop:**
|
|
78897
78897
|
- Review completed work before moving to the next slice.
|
|
78898
78898
|
- Send back with specific feedback if requirements aren't met.
|
|
78899
|
-
- ${feedingNote}
|
|
78899
|
+
- ${feedingNote}.
|
|
78900
|
+
|
|
78901
|
+
**When enhancement is enabled:** See \`<handoff-enhancer>\` in task delivery — one check-in per delegation before builder.`;
|
|
78900
78902
|
}
|
|
78901
78903
|
function getDelegationGuidelinesSection(config3, options) {
|
|
78902
78904
|
const feedingNote = config3.hasBuilder ? "Feed slices to the builder incrementally — one at a time, not all at once" : "When implementing yourself, tackle one layer at a time — avoid large monolithic changes";
|
|
@@ -78914,9 +78916,10 @@ function getDelegationGuidelinesSection(config3, options) {
|
|
|
78914
78916
|
function buildHandoffRuleLines(config3) {
|
|
78915
78917
|
return [
|
|
78916
78918
|
config3.hasBuilder ? "- **To delegate implementation** → Hand off to `builder` with clear requirements" : "- **To implement** → Work on the chatroom task directly (you are acting as implementer)",
|
|
78919
|
+
config3.hasBuilder ? "- **When enhancement is enabled** → See `<handoff-enhancer>` in task delivery before each builder delegation" : null,
|
|
78917
78920
|
"- **To deliver to user** → Hand off to `user` with a complete, standalone summary\n ⚠️ The user can ONLY see the handoff-to-user message — progress reports and all other messages are invisible to them. Write the handoff as a self-contained document: include all relevant context, results, and next steps without assuming the user read any prior conversation.",
|
|
78918
78921
|
config3.hasBuilder ? "- **For rework** → Hand off back to `builder` with specific feedback on what needs to change" : "- **For rework** → Revise your implementation directly and re-validate"
|
|
78919
|
-
].join(`
|
|
78922
|
+
].filter((line) => line !== null).join(`
|
|
78920
78923
|
`);
|
|
78921
78924
|
}
|
|
78922
78925
|
function getHandoffRulesSection(config3, nativeIntegration) {
|
|
@@ -78932,7 +78935,7 @@ var init_handoff_rules = () => {};
|
|
|
78932
78935
|
|
|
78933
78936
|
// ../../services/backend/prompts/cli/sections/when-work-comes-back.ts
|
|
78934
78937
|
function getWhenWorkComesBackSection(config3) {
|
|
78935
|
-
const reworkLine = config3.hasBuilder ? "3. If requirements are NOT met → hand back to `builder` for rework" : "3. If requirements are NOT met
|
|
78938
|
+
const reworkLine = config3.hasBuilder ? "3. If requirements are NOT met (including partial work) → hand back to `builder` for rework" : "3. If requirements are NOT met (including partial work) → revise and re-validate";
|
|
78936
78939
|
return `**When you receive work back from team members:**
|
|
78937
78940
|
1. Review the completed work against the original user request
|
|
78938
78941
|
2. If requirements are met → deliver to \`user\`
|
|
@@ -82333,7 +82336,7 @@ function renderBacklogAttachments(items, ctx) {
|
|
|
82333
82336
|
for (const item of items) {
|
|
82334
82337
|
lines.push(` <attachment type="backlog" backlog-item-id="${escapeXmlAttribute(item._id)}">`);
|
|
82335
82338
|
lines.push(...xmlTextElement("content", item.content, " "));
|
|
82336
|
-
lines.push(` <hint>Work on this item.
|
|
82339
|
+
lines.push(` <hint>Work on this item. Verified end-to-end + PR ready: chatroom backlog mark-for-review --chatroom-id="${escapeXmlAttribute(ctx.chatroomId)}" --role="${escapeXmlAttribute(ctx.role)}" --backlog-item-id=${item._id}</hint>`);
|
|
82337
82340
|
lines.push(` </attachment>`);
|
|
82338
82341
|
}
|
|
82339
82342
|
return lines;
|
|
@@ -82439,7 +82442,7 @@ function renderContextSection(input, chatroomId, role) {
|
|
|
82439
82442
|
"</context>"
|
|
82440
82443
|
];
|
|
82441
82444
|
if (ctx.triggerMessageContent) {
|
|
82442
|
-
lines.push(`(
|
|
82445
|
+
lines.push(`(Trigger: chatroom context read --chatroom-id="${chatroomId}" --role="${role}")`);
|
|
82443
82446
|
}
|
|
82444
82447
|
lines.push(...renderStalenessNotice(ctx.elapsedHours));
|
|
82445
82448
|
return lines;
|
|
@@ -82451,7 +82454,7 @@ function renderTaskPrompt(input) {
|
|
|
82451
82454
|
lines.push(` Task ID: ${taskId}`);
|
|
82452
82455
|
lines.push(` Status: ${status3}`);
|
|
82453
82456
|
if (input.context) {
|
|
82454
|
-
lines.push("On conflict,
|
|
82457
|
+
lines.push("On conflict, message wins over background context.");
|
|
82455
82458
|
}
|
|
82456
82459
|
lines.push(...renderDivergenceWarnings(input));
|
|
82457
82460
|
lines.push(`
|
|
@@ -82748,14 +82751,58 @@ var init_skill = __esm(() => {
|
|
|
82748
82751
|
init_convex_error();
|
|
82749
82752
|
});
|
|
82750
82753
|
|
|
82754
|
+
// src/commands/messages/messages-fs-service.ts
|
|
82755
|
+
import * as nodeFs2 from "node:fs/promises";
|
|
82756
|
+
function buildMessageMarkdown(msg) {
|
|
82757
|
+
const ts = new Date(msg._creationTime).toISOString();
|
|
82758
|
+
const parts2 = [];
|
|
82759
|
+
parts2.push("---");
|
|
82760
|
+
parts2.push(`id: ${msg._id}`);
|
|
82761
|
+
parts2.push(`createdAt: ${ts}`);
|
|
82762
|
+
parts2.push(`senderRole: ${msg.senderRole}`);
|
|
82763
|
+
parts2.push(`type: ${msg.type}`);
|
|
82764
|
+
if (msg.targetRole)
|
|
82765
|
+
parts2.push(`targetRole: ${msg.targetRole}`);
|
|
82766
|
+
if (msg.classification)
|
|
82767
|
+
parts2.push(`classification: ${msg.classification}`);
|
|
82768
|
+
if (msg.taskStatus)
|
|
82769
|
+
parts2.push(`taskStatus: ${msg.taskStatus}`);
|
|
82770
|
+
if (msg.featureTitle)
|
|
82771
|
+
parts2.push(`featureTitle: ${msg.featureTitle}`);
|
|
82772
|
+
parts2.push("---");
|
|
82773
|
+
parts2.push("");
|
|
82774
|
+
parts2.push(msg.content);
|
|
82775
|
+
return parts2.join(`
|
|
82776
|
+
`);
|
|
82777
|
+
}
|
|
82778
|
+
var MessagesFsService, MessagesFsServiceLive;
|
|
82779
|
+
var init_messages_fs_service = __esm(() => {
|
|
82780
|
+
init_esm();
|
|
82781
|
+
MessagesFsService = class MessagesFsService extends exports_Context.Tag("MessagesFsService")() {
|
|
82782
|
+
};
|
|
82783
|
+
MessagesFsServiceLive = exports_Layer.succeed(MessagesFsService, {
|
|
82784
|
+
writeFile: (path3, data) => exports_Effect.tryPromise({
|
|
82785
|
+
try: () => nodeFs2.writeFile(path3, data, "utf-8"),
|
|
82786
|
+
catch: (e) => e instanceof Error ? e : new Error(String(e))
|
|
82787
|
+
}),
|
|
82788
|
+
mkdir: (path3, opts) => exports_Effect.tryPromise({
|
|
82789
|
+
try: () => nodeFs2.mkdir(path3, opts),
|
|
82790
|
+
catch: (e) => e instanceof Error ? e : new Error(String(e))
|
|
82791
|
+
})
|
|
82792
|
+
});
|
|
82793
|
+
});
|
|
82794
|
+
|
|
82751
82795
|
// src/commands/messages/index.ts
|
|
82752
82796
|
var exports_messages = {};
|
|
82753
82797
|
__export(exports_messages, {
|
|
82754
82798
|
listSinceMessageEffect: () => listSinceMessageEffect,
|
|
82755
82799
|
listSinceMessage: () => listSinceMessage,
|
|
82756
82800
|
listBySenderRoleEffect: () => listBySenderRoleEffect,
|
|
82757
|
-
listBySenderRole: () => listBySenderRole
|
|
82801
|
+
listBySenderRole: () => listBySenderRole,
|
|
82802
|
+
exportMessagesEffect: () => exportMessagesEffect,
|
|
82803
|
+
exportMessages: () => exportMessages
|
|
82758
82804
|
});
|
|
82805
|
+
import * as nodePath2 from "node:path";
|
|
82759
82806
|
async function createDefaultDeps14() {
|
|
82760
82807
|
const client4 = await getConvexClient();
|
|
82761
82808
|
return {
|
|
@@ -82826,6 +82873,20 @@ async function listSinceMessage(chatroomId, options, deps) {
|
|
|
82826
82873
|
const layer = commandServicesLayerFromDeps(d);
|
|
82827
82874
|
await exports_Effect.runPromise(listSinceMessageEffect(chatroomId, options).pipe(exports_Effect.catchAll((err) => handleMessagesError(err)), exports_Effect.provide(layer)));
|
|
82828
82875
|
}
|
|
82876
|
+
async function exportMessages(chatroomId, options, deps) {
|
|
82877
|
+
const d = deps ?? await createDefaultDeps14();
|
|
82878
|
+
const layer = commandServicesLayerFromDeps(d);
|
|
82879
|
+
await exports_Effect.runPromise(exportMessagesEffect(chatroomId, options).pipe(exports_Effect.catchAll((err) => {
|
|
82880
|
+
if ("_tag" in err) {
|
|
82881
|
+
return handleMessagesError(err);
|
|
82882
|
+
}
|
|
82883
|
+
return exports_Effect.sync(() => {
|
|
82884
|
+
console.error(`
|
|
82885
|
+
❌ Export failed: ${err.message}`);
|
|
82886
|
+
process.exit(1);
|
|
82887
|
+
});
|
|
82888
|
+
}), exports_Effect.provide(exports_Layer.mergeAll(layer, MessagesFsServiceLive))));
|
|
82889
|
+
}
|
|
82829
82890
|
var listBySenderRoleEffect = (chatroomId, options) => exports_Effect.gen(function* () {
|
|
82830
82891
|
const backend2 = yield* BackendService;
|
|
82831
82892
|
const sessionId = yield* requireSessionIdEffect((a) => ({
|
|
@@ -82916,9 +82977,59 @@ ${roleIndicator} ${message.senderRole}${message.targetRole ? ` → ${message.tar
|
|
|
82916
82977
|
` + "─".repeat(60));
|
|
82917
82978
|
console.log(`\uD83D\uDCA1 Use --full to see complete message content`);
|
|
82918
82979
|
});
|
|
82980
|
+
}), exportMessagesEffect = (chatroomId, options) => exports_Effect.gen(function* () {
|
|
82981
|
+
const backend2 = yield* BackendService;
|
|
82982
|
+
const fs11 = yield* MessagesFsService;
|
|
82983
|
+
const sessionId = yield* requireSessionIdEffect((a) => ({
|
|
82984
|
+
_tag: "NotAuthenticated",
|
|
82985
|
+
convexUrl: a.convexUrl,
|
|
82986
|
+
otherUrls: a.otherUrls
|
|
82987
|
+
}));
|
|
82988
|
+
yield* validateChatroomIdEffect(chatroomId, (id3) => ({
|
|
82989
|
+
_tag: "InvalidChatroomId",
|
|
82990
|
+
id: id3
|
|
82991
|
+
}));
|
|
82992
|
+
const messagesResult = yield* exports_Effect.either(backend2.query(api.messages.listBySenderRole, {
|
|
82993
|
+
sessionId,
|
|
82994
|
+
chatroomId,
|
|
82995
|
+
senderRole: options.senderRole || "planner",
|
|
82996
|
+
limit: options.limit
|
|
82997
|
+
}));
|
|
82998
|
+
if (messagesResult._tag === "Left") {
|
|
82999
|
+
return yield* exports_Effect.fail({
|
|
83000
|
+
_tag: "QueryFailed",
|
|
83001
|
+
cause: messagesResult.left
|
|
83002
|
+
});
|
|
83003
|
+
}
|
|
83004
|
+
const messages = messagesResult.right;
|
|
83005
|
+
if (messages.length === 0) {
|
|
83006
|
+
yield* exports_Effect.sync(() => console.log("No messages to export."));
|
|
83007
|
+
return;
|
|
83008
|
+
}
|
|
83009
|
+
const dir = options.exportPath || `.chatroom/exports/messages/${chatroomId}`;
|
|
83010
|
+
yield* fs11.mkdir(dir, { recursive: true });
|
|
83011
|
+
const manifest = [];
|
|
83012
|
+
for (const msg of messages) {
|
|
83013
|
+
const filename = `${msg._creationTime}-${msg.senderRole}-${msg._id.slice(0, 8)}.md`;
|
|
83014
|
+
const markdown = buildMessageMarkdown(msg);
|
|
83015
|
+
yield* fs11.writeFile(nodePath2.join(dir, filename), markdown);
|
|
83016
|
+
manifest.push({
|
|
83017
|
+
id: msg._id,
|
|
83018
|
+
senderRole: msg.senderRole,
|
|
83019
|
+
createdAt: msg._creationTime,
|
|
83020
|
+
filename
|
|
83021
|
+
});
|
|
83022
|
+
}
|
|
83023
|
+
yield* fs11.writeFile(nodePath2.join(dir, "manifest.json"), JSON.stringify(manifest, null, 2));
|
|
83024
|
+
yield* exports_Effect.sync(() => {
|
|
83025
|
+
console.log(`
|
|
83026
|
+
\uD83D\uDCE8 Exported ${messages.length} messages to ${dir}`);
|
|
83027
|
+
console.log(` Manifest: ${dir}/manifest.json`);
|
|
83028
|
+
});
|
|
82919
83029
|
});
|
|
82920
83030
|
var init_messages = __esm(() => {
|
|
82921
83031
|
init_esm();
|
|
83032
|
+
init_messages_fs_service();
|
|
82922
83033
|
init_api3();
|
|
82923
83034
|
init_storage();
|
|
82924
83035
|
init_client2();
|
|
@@ -99681,17 +99792,17 @@ import {
|
|
|
99681
99792
|
writeFileSync as writeFileSync3
|
|
99682
99793
|
} from "node:fs";
|
|
99683
99794
|
import { homedir as homedir5 } from "node:os";
|
|
99684
|
-
import { join as
|
|
99795
|
+
import { join as join16 } from "node:path";
|
|
99685
99796
|
function getUrlHash() {
|
|
99686
99797
|
const url3 = getConvexUrl();
|
|
99687
99798
|
return createHash2("sha256").update(url3).digest("hex").substring(0, 8);
|
|
99688
99799
|
}
|
|
99689
99800
|
function getChildPidsFilePath() {
|
|
99690
|
-
const dir =
|
|
99691
|
-
return
|
|
99801
|
+
const dir = join16(homedir5(), ".chatroom");
|
|
99802
|
+
return join16(dir, `daemon-children-${getUrlHash()}.pids`);
|
|
99692
99803
|
}
|
|
99693
99804
|
function ensureChatroomDir2() {
|
|
99694
|
-
const dir =
|
|
99805
|
+
const dir = join16(homedir5(), ".chatroom");
|
|
99695
99806
|
if (!existsSync5(dir)) {
|
|
99696
99807
|
mkdirSync4(dir, { recursive: true, mode: 448 });
|
|
99697
99808
|
}
|
|
@@ -100021,9 +100132,9 @@ var init_log_observer_sync = __esm(() => {
|
|
|
100021
100132
|
});
|
|
100022
100133
|
|
|
100023
100134
|
// src/commands/machine/daemon-start/handlers/process/output-store.ts
|
|
100024
|
-
import { appendFile as appendFile2, mkdir as
|
|
100135
|
+
import { appendFile as appendFile2, mkdir as mkdir8, readFile as readFile6, rm } from "node:fs/promises";
|
|
100025
100136
|
import { tmpdir } from "node:os";
|
|
100026
|
-
import { join as
|
|
100137
|
+
import { join as join17 } from "node:path";
|
|
100027
100138
|
|
|
100028
100139
|
class TempFileOutputStore {
|
|
100029
100140
|
state;
|
|
@@ -100086,11 +100197,11 @@ function createOutputStore(runId) {
|
|
|
100086
100197
|
if (!RUN_ID_RE.test(runId)) {
|
|
100087
100198
|
throw new Error(`Invalid runId: ${runId}`);
|
|
100088
100199
|
}
|
|
100089
|
-
const filePath =
|
|
100200
|
+
const filePath = join17(TEMP_DIR, `${runId}.log`);
|
|
100090
100201
|
return new TempFileOutputStore(filePath);
|
|
100091
100202
|
}
|
|
100092
100203
|
async function ensureTempDir() {
|
|
100093
|
-
await
|
|
100204
|
+
await mkdir8(TEMP_DIR, { recursive: true });
|
|
100094
100205
|
}
|
|
100095
100206
|
async function cleanOrphanTempFiles() {
|
|
100096
100207
|
try {
|
|
@@ -100100,7 +100211,7 @@ async function cleanOrphanTempFiles() {
|
|
|
100100
100211
|
var TAIL_WINDOW_BYTES, TEMP_DIR, RUN_ID_RE, MAX_TAIL_LINES_V2 = 50;
|
|
100101
100212
|
var init_output_store = __esm(() => {
|
|
100102
100213
|
TAIL_WINDOW_BYTES = 32 * 1024;
|
|
100103
|
-
TEMP_DIR =
|
|
100214
|
+
TEMP_DIR = join17(tmpdir(), "chatroom-cli", "runs");
|
|
100104
100215
|
RUN_ID_RE = /^[a-z0-9]+$/i;
|
|
100105
100216
|
});
|
|
100106
100217
|
|
|
@@ -100791,7 +100902,7 @@ var init_pick_folder = () => {};
|
|
|
100791
100902
|
import { createHash as createHash3 } from "node:crypto";
|
|
100792
100903
|
import { existsSync as existsSync6, readFileSync as readFileSync8, writeFileSync as writeFileSync4, unlinkSync as unlinkSync2, mkdirSync as mkdirSync5 } from "node:fs";
|
|
100793
100904
|
import { homedir as homedir6 } from "node:os";
|
|
100794
|
-
import { join as
|
|
100905
|
+
import { join as join18 } from "node:path";
|
|
100795
100906
|
function getUrlHash2() {
|
|
100796
100907
|
const url3 = getConvexUrl();
|
|
100797
100908
|
return createHash3("sha256").update(url3).digest("hex").substring(0, 8);
|
|
@@ -100805,7 +100916,7 @@ function ensureChatroomDir3() {
|
|
|
100805
100916
|
}
|
|
100806
100917
|
}
|
|
100807
100918
|
function getPidFilePath() {
|
|
100808
|
-
return
|
|
100919
|
+
return join18(CHATROOM_DIR4, getPidFileName());
|
|
100809
100920
|
}
|
|
100810
100921
|
function isProcessRunning(pid) {
|
|
100811
100922
|
try {
|
|
@@ -100902,7 +101013,7 @@ function releaseLock() {
|
|
|
100902
101013
|
var CHATROOM_DIR4, LOCK_RETRY_INTERVAL_MS = 500, LOCK_RETRY_MAX_WAIT_MS = 15000;
|
|
100903
101014
|
var init_pid = __esm(() => {
|
|
100904
101015
|
init_client2();
|
|
100905
|
-
CHATROOM_DIR4 =
|
|
101016
|
+
CHATROOM_DIR4 = join18(homedir6(), ".chatroom");
|
|
100906
101017
|
});
|
|
100907
101018
|
|
|
100908
101019
|
// src/infrastructure/harnesses/claude-sdk/claude-session.ts
|
|
@@ -103884,7 +103995,7 @@ var init_start_subscriptions2 = __esm(() => {
|
|
|
103884
103995
|
});
|
|
103885
103996
|
|
|
103886
103997
|
// src/commands/machine/daemon-start/enhancer/constants.ts
|
|
103887
|
-
var ENHANCER_AGENT_ROLE = "enhancer";
|
|
103998
|
+
var ENHANCER_AGENT_ROLE = "enhancer", ENHANCER_AGENT_END_GRACE_MS = 3000, ENHANCER_JOB_POLL_INTERVAL_MS = 500, ENHANCER_SILENCE_TIMEOUT_MS = 120000;
|
|
103888
103999
|
|
|
103889
104000
|
// src/commands/machine/daemon-start/enhancer/enhancer-log.ts
|
|
103890
104001
|
function formatEnhancerLogLine(message) {
|
|
@@ -103899,6 +104010,114 @@ function writeEnhancerLog(message) {
|
|
|
103899
104010
|
}
|
|
103900
104011
|
var ENHANCER_LOG_PREFIX = "[enhancer]";
|
|
103901
104012
|
|
|
104013
|
+
// src/commands/machine/daemon-start/enhancer/wait-for-enhancer-job.ts
|
|
104014
|
+
async function waitForEnhancerJobResolution(params) {
|
|
104015
|
+
const { sessionId, chatroomId, jobId, backend: backend2, onFailure, onSalvageComplete } = params;
|
|
104016
|
+
let outcome = null;
|
|
104017
|
+
let lastActivityAt = Date.now();
|
|
104018
|
+
let salvagedText = "";
|
|
104019
|
+
const pollInterval = setInterval(async () => {
|
|
104020
|
+
if (outcome)
|
|
104021
|
+
return;
|
|
104022
|
+
try {
|
|
104023
|
+
const status3 = await backend2.query(api.web.enhancer.index.getJob, {
|
|
104024
|
+
sessionId,
|
|
104025
|
+
chatroomId,
|
|
104026
|
+
jobId
|
|
104027
|
+
});
|
|
104028
|
+
if (status3?.status === "complete") {
|
|
104029
|
+
outcome = "complete";
|
|
104030
|
+
writeEnhancerLog(`completed job=${jobId}`);
|
|
104031
|
+
}
|
|
104032
|
+
} catch {}
|
|
104033
|
+
}, ENHANCER_JOB_POLL_INTERVAL_MS);
|
|
104034
|
+
const silenceInterval = setInterval(() => {
|
|
104035
|
+
if (outcome)
|
|
104036
|
+
return;
|
|
104037
|
+
if (Date.now() - lastActivityAt >= ENHANCER_SILENCE_TIMEOUT_MS) {
|
|
104038
|
+
outcome = "failed";
|
|
104039
|
+
writeEnhancerLog(`silence timeout — no activity for ${ENHANCER_SILENCE_TIMEOUT_MS}ms`);
|
|
104040
|
+
onFailure("Enhancer silence timeout — no output received", false);
|
|
104041
|
+
}
|
|
104042
|
+
}, ENHANCER_JOB_POLL_INTERVAL_MS);
|
|
104043
|
+
params.onAssistantText?.((text) => {
|
|
104044
|
+
lastActivityAt = Date.now();
|
|
104045
|
+
salvagedText += text;
|
|
104046
|
+
});
|
|
104047
|
+
params.onAgentEnd?.(() => {
|
|
104048
|
+
if (outcome)
|
|
104049
|
+
return;
|
|
104050
|
+
const check4 = () => {
|
|
104051
|
+
if (outcome)
|
|
104052
|
+
return;
|
|
104053
|
+
backend2.query(api.web.enhancer.index.getJob, {
|
|
104054
|
+
sessionId,
|
|
104055
|
+
chatroomId,
|
|
104056
|
+
jobId
|
|
104057
|
+
}).then((status3) => {
|
|
104058
|
+
if (outcome)
|
|
104059
|
+
return;
|
|
104060
|
+
if (status3?.status === "complete") {
|
|
104061
|
+
outcome = "complete";
|
|
104062
|
+
return;
|
|
104063
|
+
}
|
|
104064
|
+
if (status3?.status === "running") {
|
|
104065
|
+
const trimmed = salvagedText.trim();
|
|
104066
|
+
if (trimmed && onSalvageComplete) {
|
|
104067
|
+
onSalvageComplete(trimmed).then(() => {
|
|
104068
|
+
if (outcome)
|
|
104069
|
+
return;
|
|
104070
|
+
backend2.query(api.web.enhancer.index.getJob, {
|
|
104071
|
+
sessionId,
|
|
104072
|
+
chatroomId,
|
|
104073
|
+
jobId
|
|
104074
|
+
}).then((afterSalvage) => {
|
|
104075
|
+
if (afterSalvage?.status === "complete") {
|
|
104076
|
+
outcome = "complete";
|
|
104077
|
+
writeEnhancerLog("agent_end: salvaged assistant text via complete");
|
|
104078
|
+
return;
|
|
104079
|
+
}
|
|
104080
|
+
outcome = "failed";
|
|
104081
|
+
writeEnhancerLog("agent_end: turn ended without complete — failing terminal");
|
|
104082
|
+
onFailure("Agent exited without completing enhancer job", true);
|
|
104083
|
+
});
|
|
104084
|
+
}).catch(() => {
|
|
104085
|
+
outcome = "failed";
|
|
104086
|
+
writeEnhancerLog("agent_end: turn ended without complete — failing terminal");
|
|
104087
|
+
onFailure("Agent exited without completing enhancer job", true);
|
|
104088
|
+
});
|
|
104089
|
+
} else {
|
|
104090
|
+
outcome = "failed";
|
|
104091
|
+
writeEnhancerLog("agent_end: turn ended without complete — failing terminal");
|
|
104092
|
+
onFailure("Agent exited without completing enhancer job", true);
|
|
104093
|
+
}
|
|
104094
|
+
}
|
|
104095
|
+
});
|
|
104096
|
+
};
|
|
104097
|
+
setTimeout(check4, ENHANCER_AGENT_END_GRACE_MS);
|
|
104098
|
+
});
|
|
104099
|
+
params.onExit(() => {
|
|
104100
|
+
if (outcome)
|
|
104101
|
+
return;
|
|
104102
|
+
outcome = "failed";
|
|
104103
|
+
onFailure("Agent process exited without completing enhancer job", false);
|
|
104104
|
+
});
|
|
104105
|
+
await new Promise((resolve4) => {
|
|
104106
|
+
const check4 = setInterval(() => {
|
|
104107
|
+
if (outcome) {
|
|
104108
|
+
clearInterval(check4);
|
|
104109
|
+
resolve4();
|
|
104110
|
+
}
|
|
104111
|
+
}, 100);
|
|
104112
|
+
});
|
|
104113
|
+
clearInterval(pollInterval);
|
|
104114
|
+
clearInterval(silenceInterval);
|
|
104115
|
+
return outcome ?? "failed";
|
|
104116
|
+
}
|
|
104117
|
+
var init_wait_for_enhancer_job = __esm(() => {
|
|
104118
|
+
init_api3();
|
|
104119
|
+
});
|
|
104120
|
+
|
|
103902
104121
|
// src/commands/machine/daemon-start/enhancer/job-subscriber.ts
|
|
103903
104122
|
function startEnhancerJobSubscriber(sessionId, machineId, convexUrl, backend2, wsClient2, agentServices) {
|
|
103904
104123
|
const inFlight = new Set;
|
|
@@ -103911,6 +104130,8 @@ function startEnhancerJobSubscriber(sessionId, machineId, convexUrl, backend2, w
|
|
|
103911
104130
|
let claimed = false;
|
|
103912
104131
|
let chatroomId = job.chatroomId;
|
|
103913
104132
|
let jobId = job.jobId;
|
|
104133
|
+
let spawnResult = null;
|
|
104134
|
+
let service3 = null;
|
|
103914
104135
|
try {
|
|
103915
104136
|
const claim = await backend2.mutation(api.daemon.enhancer.index.claimForSpawn, {
|
|
103916
104137
|
sessionId,
|
|
@@ -103928,7 +104149,7 @@ function startEnhancerJobSubscriber(sessionId, machineId, convexUrl, backend2, w
|
|
|
103928
104149
|
chatroomId = payload.chatroomId;
|
|
103929
104150
|
jobId = payload.jobId;
|
|
103930
104151
|
writeEnhancerLog(`spawning harness=${payload.agentHarness} model=${payload.model} job=${payload.jobId}`);
|
|
103931
|
-
|
|
104152
|
+
service3 = agentServices.get(payload.agentHarness) ?? null;
|
|
103932
104153
|
if (!service3) {
|
|
103933
104154
|
await backend2.mutation(api.web.enhancer.index.recordAttemptFailure, {
|
|
103934
104155
|
sessionId,
|
|
@@ -103938,7 +104159,7 @@ function startEnhancerJobSubscriber(sessionId, machineId, convexUrl, backend2, w
|
|
|
103938
104159
|
});
|
|
103939
104160
|
return;
|
|
103940
104161
|
}
|
|
103941
|
-
|
|
104162
|
+
spawnResult = await service3.spawn({
|
|
103942
104163
|
workingDir: payload.workingDir,
|
|
103943
104164
|
prompt: createSpawnPrompt(payload.taskEnvelope),
|
|
103944
104165
|
systemPrompt: payload.systemPrompt,
|
|
@@ -103953,29 +104174,34 @@ function startEnhancerJobSubscriber(sessionId, machineId, convexUrl, backend2, w
|
|
|
103953
104174
|
spawnResult.onLogLine?.((line) => {
|
|
103954
104175
|
writeEnhancerLog(line);
|
|
103955
104176
|
});
|
|
103956
|
-
|
|
103957
|
-
|
|
103958
|
-
writeEnhancerLog(`text] ${text}`);
|
|
103959
|
-
});
|
|
103960
|
-
await new Promise((resolve4) => {
|
|
103961
|
-
spawnResult.onExit(() => resolve4());
|
|
103962
|
-
});
|
|
103963
|
-
const status3 = await backend2.query(api.web.enhancer.index.getJob, {
|
|
104177
|
+
const sr = spawnResult;
|
|
104178
|
+
const outcome = await waitForEnhancerJobResolution({
|
|
103964
104179
|
sessionId,
|
|
103965
104180
|
chatroomId: payload.chatroomId,
|
|
103966
|
-
jobId: payload.jobId
|
|
104181
|
+
jobId: payload.jobId,
|
|
104182
|
+
backend: backend2,
|
|
104183
|
+
onAssistantText: sr.onAssistantText ? (cb) => sr.onAssistantText(cb) : undefined,
|
|
104184
|
+
onAgentEnd: sr.onAgentEnd ? (cb) => sr.onAgentEnd(cb) : undefined,
|
|
104185
|
+
onExit: (cb) => sr.onExit(() => cb()),
|
|
104186
|
+
onSalvageComplete: async (content) => {
|
|
104187
|
+
await backend2.mutation(api.web.enhancer.index.complete, {
|
|
104188
|
+
sessionId,
|
|
104189
|
+
chatroomId: payload.chatroomId,
|
|
104190
|
+
jobId: payload.jobId,
|
|
104191
|
+
enhancedContent: content
|
|
104192
|
+
});
|
|
104193
|
+
},
|
|
104194
|
+
onFailure: async (error51, forceTerminal) => {
|
|
104195
|
+
await backend2.mutation(api.web.enhancer.index.recordAttemptFailure, {
|
|
104196
|
+
sessionId,
|
|
104197
|
+
chatroomId: payload.chatroomId,
|
|
104198
|
+
jobId: payload.jobId,
|
|
104199
|
+
error: error51,
|
|
104200
|
+
...forceTerminal ? { forceTerminal: true } : {}
|
|
104201
|
+
});
|
|
104202
|
+
}
|
|
103967
104203
|
});
|
|
103968
|
-
|
|
103969
|
-
writeEnhancerLog(`completed job=${payload.jobId}`);
|
|
103970
|
-
}
|
|
103971
|
-
if (status3?.status === "running") {
|
|
103972
|
-
await backend2.mutation(api.web.enhancer.index.recordAttemptFailure, {
|
|
103973
|
-
sessionId,
|
|
103974
|
-
chatroomId: payload.chatroomId,
|
|
103975
|
-
jobId: payload.jobId,
|
|
103976
|
-
error: "Agent exited without completing enhancer job"
|
|
103977
|
-
});
|
|
103978
|
-
}
|
|
104204
|
+
writeEnhancerLog(`completed job=${jobId}`);
|
|
103979
104205
|
} catch (err) {
|
|
103980
104206
|
writeEnhancerLog(`error: ${err instanceof Error ? err.message : String(err)}`);
|
|
103981
104207
|
if (claimed) {
|
|
@@ -103988,6 +104214,11 @@ function startEnhancerJobSubscriber(sessionId, machineId, convexUrl, backend2, w
|
|
|
103988
104214
|
}
|
|
103989
104215
|
} finally {
|
|
103990
104216
|
inFlight.delete(job.jobId);
|
|
104217
|
+
if (spawnResult && service3) {
|
|
104218
|
+
try {
|
|
104219
|
+
await service3.stop(spawnResult.pid);
|
|
104220
|
+
} catch {}
|
|
104221
|
+
}
|
|
103991
104222
|
}
|
|
103992
104223
|
})();
|
|
103993
104224
|
}
|
|
@@ -103995,6 +104226,7 @@ function startEnhancerJobSubscriber(sessionId, machineId, convexUrl, backend2, w
|
|
|
103995
104226
|
return { stop: unsub };
|
|
103996
104227
|
}
|
|
103997
104228
|
var init_job_subscriber = __esm(() => {
|
|
104229
|
+
init_wait_for_enhancer_job();
|
|
103998
104230
|
init_api3();
|
|
103999
104231
|
});
|
|
104000
104232
|
|
|
@@ -104112,11 +104344,11 @@ async function getWorkspacesForMachine(deps) {
|
|
|
104112
104344
|
return store.workspaces;
|
|
104113
104345
|
}
|
|
104114
104346
|
try {
|
|
104115
|
-
const
|
|
104347
|
+
const workingDirs = await deps.backend.query(api.workspaces.listRecentlyObservedWorkspacesForMachine, {
|
|
104116
104348
|
sessionId: deps.sessionId,
|
|
104117
104349
|
machineId: deps.machineId
|
|
104118
104350
|
});
|
|
104119
|
-
const mapped =
|
|
104351
|
+
const mapped = (workingDirs ?? []).map((workingDir) => ({ workingDir }));
|
|
104120
104352
|
if (store) {
|
|
104121
104353
|
store.workspaces = mapped;
|
|
104122
104354
|
store.updatedAt = Date.now();
|
|
@@ -107430,7 +107662,7 @@ function diffPathIndexes(previous, next4) {
|
|
|
107430
107662
|
import { createHash as createHash6, randomUUID as randomUUID8 } from "node:crypto";
|
|
107431
107663
|
import * as fs11 from "node:fs/promises";
|
|
107432
107664
|
import { homedir as homedir7 } from "node:os";
|
|
107433
|
-
import { join as
|
|
107665
|
+
import { join as join21 } from "node:path";
|
|
107434
107666
|
function workspaceKeyFor(workingDir) {
|
|
107435
107667
|
const normalized = normalizeWorkingDirForLookup(workingDir);
|
|
107436
107668
|
return createHash6("sha256").update(normalized).digest("hex").slice(0, 16);
|
|
@@ -107444,10 +107676,10 @@ function buildPathIndex(entries2) {
|
|
|
107444
107676
|
}
|
|
107445
107677
|
function manifestPath(machineId, workingDir) {
|
|
107446
107678
|
const key = workspaceKeyFor(workingDir);
|
|
107447
|
-
return
|
|
107679
|
+
return join21(SYNC_STATE_DIR, machineId, key, "manifest.json");
|
|
107448
107680
|
}
|
|
107449
107681
|
async function ensureDir(filePath) {
|
|
107450
|
-
await fs11.mkdir(
|
|
107682
|
+
await fs11.mkdir(join21(filePath, ".."), { recursive: true, mode: 448 });
|
|
107451
107683
|
}
|
|
107452
107684
|
async function loadWorkspaceSyncManifest(machineId, workingDir) {
|
|
107453
107685
|
try {
|
|
@@ -107507,7 +107739,7 @@ function entriesFromPathIndex(paths) {
|
|
|
107507
107739
|
}
|
|
107508
107740
|
var SYNC_STATE_VERSION = "2", SYNC_STATE_DIR;
|
|
107509
107741
|
var init_workspace_sync_state = __esm(() => {
|
|
107510
|
-
SYNC_STATE_DIR =
|
|
107742
|
+
SYNC_STATE_DIR = join21(homedir7(), ".chatroom", "sync-state");
|
|
107511
107743
|
});
|
|
107512
107744
|
|
|
107513
107745
|
// src/infrastructure/services/workspace/workspace-file-tree-coordinator.ts
|
|
@@ -107837,18 +108069,18 @@ async function syncScannedFileTree(session2, normalizedWorkingDir, tree, dataHas
|
|
|
107837
108069
|
function toDeltaOperations(delta) {
|
|
107838
108070
|
return [
|
|
107839
108071
|
...delta.added.map((entry) => ({
|
|
107840
|
-
|
|
107841
|
-
|
|
107842
|
-
|
|
108072
|
+
o: "a",
|
|
108073
|
+
p: entry.path,
|
|
108074
|
+
e: entry.type === "directory" ? "d" : "f"
|
|
107843
108075
|
})),
|
|
107844
108076
|
...delta.removed.map((entryPath) => ({
|
|
107845
|
-
|
|
107846
|
-
|
|
108077
|
+
o: "r",
|
|
108078
|
+
p: entryPath
|
|
107847
108079
|
})),
|
|
107848
108080
|
...delta.typeChanged.map((entry) => ({
|
|
107849
|
-
|
|
107850
|
-
|
|
107851
|
-
|
|
108081
|
+
o: "t",
|
|
108082
|
+
p: entry.path,
|
|
108083
|
+
e: entry.type === "directory" ? "d" : "f"
|
|
107852
108084
|
}))
|
|
107853
108085
|
];
|
|
107854
108086
|
}
|
|
@@ -107982,7 +108214,7 @@ function unsupportedFileWriteOperationMessage(operation) {
|
|
|
107982
108214
|
}
|
|
107983
108215
|
|
|
107984
108216
|
// src/commands/machine/daemon-start/file-write-fulfillment.ts
|
|
107985
|
-
import { access as access4, mkdir as
|
|
108217
|
+
import { access as access4, mkdir as mkdir10, rename as rename4, rm as rm3, writeFile as writeFile9 } from "node:fs/promises";
|
|
107986
108218
|
import { dirname as dirname11 } from "node:path";
|
|
107987
108219
|
function isTerminalFileWriteError(errorMessage) {
|
|
107988
108220
|
const terminalMessages = new Set([
|
|
@@ -108035,9 +108267,9 @@ async function validateWriteOperation(operation, absolutePath) {
|
|
|
108035
108267
|
}
|
|
108036
108268
|
async function writePayloadToDisk(absolutePath, operation, content) {
|
|
108037
108269
|
if (operation === "create") {
|
|
108038
|
-
await
|
|
108270
|
+
await mkdir10(dirname11(absolutePath), { recursive: true });
|
|
108039
108271
|
}
|
|
108040
|
-
await
|
|
108272
|
+
await writeFile9(absolutePath, content);
|
|
108041
108273
|
}
|
|
108042
108274
|
async function fulfillOneFileWriteRequest(session2, request2) {
|
|
108043
108275
|
const startTime = Date.now();
|
|
@@ -108098,7 +108330,7 @@ async function fulfillOneFileWriteRequest(session2, request2) {
|
|
|
108098
108330
|
});
|
|
108099
108331
|
return;
|
|
108100
108332
|
}
|
|
108101
|
-
await
|
|
108333
|
+
await mkdir10(dirname11(targetResolved.absolutePath), { recursive: true });
|
|
108102
108334
|
await rename4(resolved.absolutePath, targetResolved.absolutePath);
|
|
108103
108335
|
await completeWriteRequest(session2, request2._id, { status: "done" });
|
|
108104
108336
|
const elapsed4 = Date.now() - startTime;
|
|
@@ -108114,7 +108346,7 @@ async function fulfillOneFileWriteRequest(session2, request2) {
|
|
|
108114
108346
|
});
|
|
108115
108347
|
return;
|
|
108116
108348
|
}
|
|
108117
|
-
await
|
|
108349
|
+
await mkdir10(resolved.absolutePath, { recursive: true });
|
|
108118
108350
|
await completeWriteRequest(session2, request2._id, { status: "done" });
|
|
108119
108351
|
const elapsed4 = Date.now() - startTime;
|
|
108120
108352
|
console.log(`[${formatTimestamp()}] ✏️ Directory mkdir fulfilled: ${filePath} (${elapsed4}ms)`);
|
|
@@ -112838,16 +113070,16 @@ var init_jsonc = __esm(() => {
|
|
|
112838
113070
|
|
|
112839
113071
|
// src/infrastructure/services/workspace/workspace-resolver.ts
|
|
112840
113072
|
import { readFile as readFile10, readdir as readdir3, stat as stat6 } from "node:fs/promises";
|
|
112841
|
-
import { join as
|
|
113073
|
+
import { join as join22, basename as basename4, resolve as resolve7 } from "node:path";
|
|
112842
113074
|
async function resolveGlobPatternStar(rootDir, cleaned) {
|
|
112843
|
-
const parentDir =
|
|
113075
|
+
const parentDir = join22(rootDir, cleaned.slice(0, -2));
|
|
112844
113076
|
try {
|
|
112845
113077
|
const entries2 = await readdir3(parentDir, { withFileTypes: true });
|
|
112846
113078
|
const dirs = [];
|
|
112847
113079
|
for (const entry of entries2) {
|
|
112848
113080
|
if (!entry.isDirectory())
|
|
112849
113081
|
continue;
|
|
112850
|
-
const dirPath =
|
|
113082
|
+
const dirPath = join22(parentDir, entry.name);
|
|
112851
113083
|
if (resolve7(dirPath).startsWith(resolve7(rootDir))) {
|
|
112852
113084
|
dirs.push(dirPath);
|
|
112853
113085
|
}
|
|
@@ -112858,7 +113090,7 @@ async function resolveGlobPatternStar(rootDir, cleaned) {
|
|
|
112858
113090
|
}
|
|
112859
113091
|
}
|
|
112860
113092
|
async function resolveLiteralPath(rootDir, cleaned) {
|
|
112861
|
-
const dir =
|
|
113093
|
+
const dir = join22(rootDir, cleaned);
|
|
112862
113094
|
try {
|
|
112863
113095
|
if (!resolve7(dir).startsWith(resolve7(rootDir)))
|
|
112864
113096
|
return [];
|
|
@@ -112878,7 +113110,7 @@ async function resolveGlobPattern(rootDir, pattern) {
|
|
|
112878
113110
|
}
|
|
112879
113111
|
async function readPackageJson(dir) {
|
|
112880
113112
|
try {
|
|
112881
|
-
const content = await readFile10(
|
|
113113
|
+
const content = await readFile10(join22(dir, "package.json"), "utf-8");
|
|
112882
113114
|
const pkg = JSON.parse(content);
|
|
112883
113115
|
return {
|
|
112884
113116
|
name: pkg.name || basename4(dir),
|
|
@@ -112890,7 +113122,7 @@ async function readPackageJson(dir) {
|
|
|
112890
113122
|
}
|
|
112891
113123
|
async function readPnpmWorkspacePatterns(rootDir) {
|
|
112892
113124
|
try {
|
|
112893
|
-
const content = await readFile10(
|
|
113125
|
+
const content = await readFile10(join22(rootDir, "pnpm-workspace.yaml"), "utf-8");
|
|
112894
113126
|
const patterns = [];
|
|
112895
113127
|
let inPackages = false;
|
|
112896
113128
|
for (const line of content.split(`
|
|
@@ -112917,7 +113149,7 @@ async function readPnpmWorkspacePatterns(rootDir) {
|
|
|
112917
113149
|
}
|
|
112918
113150
|
async function readPackageJsonWorkspacePatterns(rootDir) {
|
|
112919
113151
|
try {
|
|
112920
|
-
const content = await readFile10(
|
|
113152
|
+
const content = await readFile10(join22(rootDir, "package.json"), "utf-8");
|
|
112921
113153
|
const pkg = JSON.parse(content);
|
|
112922
113154
|
if (!pkg.workspaces)
|
|
112923
113155
|
return [];
|
|
@@ -112998,11 +113230,11 @@ var MAX_NAME_LENGTH = 256;
|
|
|
112998
113230
|
|
|
112999
113231
|
// src/infrastructure/services/workspace/command-discovery.ts
|
|
113000
113232
|
import { access as access5, readFile as readFile11 } from "node:fs/promises";
|
|
113001
|
-
import { join as
|
|
113233
|
+
import { join as join23, relative as relative4, basename as basename5 } from "node:path";
|
|
113002
113234
|
async function detectPackageManager(workingDir) {
|
|
113003
113235
|
for (const { file: file2, manager } of LOCKFILE_MAP) {
|
|
113004
113236
|
try {
|
|
113005
|
-
await access5(
|
|
113237
|
+
await access5(join23(workingDir, file2));
|
|
113006
113238
|
return manager;
|
|
113007
113239
|
} catch {}
|
|
113008
113240
|
}
|
|
@@ -113071,7 +113303,7 @@ function collectRootScriptCommands(scripts, pm, scriptPrefix, rootSw) {
|
|
|
113071
113303
|
}
|
|
113072
113304
|
async function readRootPackageJson(workingDir, pm, scriptPrefix) {
|
|
113073
113305
|
let rootPackageName = basename5(workingDir);
|
|
113074
|
-
const pkg = await readJsonFile(
|
|
113306
|
+
const pkg = await readJsonFile(join23(workingDir, "package.json"), "root package.json");
|
|
113075
113307
|
if (!pkg)
|
|
113076
113308
|
return { commands: [], rootPackageName };
|
|
113077
113309
|
if (pkg.name)
|
|
@@ -113087,7 +113319,7 @@ async function readRootPackageJson(workingDir, pm, scriptPrefix) {
|
|
|
113087
113319
|
}
|
|
113088
113320
|
async function readTurboJson(workingDir, _turboPrefix, _rootSubWorkspace) {
|
|
113089
113321
|
const turboTaskNames = [];
|
|
113090
|
-
const turbo = await readJsonFile(
|
|
113322
|
+
const turbo = await readJsonFile(join23(workingDir, "turbo.json"), "turbo.json");
|
|
113091
113323
|
if (!turbo?.tasks || typeof turbo.tasks !== "object")
|
|
113092
113324
|
return turboTaskNames;
|
|
113093
113325
|
for (const taskName of Object.keys(turbo.tasks)) {
|
|
@@ -113100,7 +113332,7 @@ async function readTurboJson(workingDir, _turboPrefix, _rootSubWorkspace) {
|
|
|
113100
113332
|
async function readDenoJson(workingDir) {
|
|
113101
113333
|
const commands = [];
|
|
113102
113334
|
for (const fileName of ["deno.json", "deno.jsonc"]) {
|
|
113103
|
-
const deno = await readJsonFile(
|
|
113335
|
+
const deno = await readJsonFile(join23(workingDir, fileName), fileName);
|
|
113104
113336
|
if (!deno?.tasks || typeof deno.tasks !== "object")
|
|
113105
113337
|
continue;
|
|
113106
113338
|
const pkgName = deno.name ?? basename5(workingDir);
|
|
@@ -113123,7 +113355,7 @@ async function readMakefile(workingDir) {
|
|
|
113123
113355
|
const commands = [];
|
|
113124
113356
|
for (const fileName of ["Makefile", "makefile"]) {
|
|
113125
113357
|
try {
|
|
113126
|
-
const content = await readFile11(
|
|
113358
|
+
const content = await readFile11(join23(workingDir, fileName), "utf-8");
|
|
113127
113359
|
const targets = parseMakefileTargets(content);
|
|
113128
113360
|
if (targets.length === 0)
|
|
113129
113361
|
continue;
|
|
@@ -113276,9 +113508,9 @@ var startObservedSyncSubscriptionEffect = (wsClient2) => exports_Effect.gen(func
|
|
|
113276
113508
|
sessionId: session2.sessionId,
|
|
113277
113509
|
machineId: session2.machineId
|
|
113278
113510
|
}, (observed) => {
|
|
113279
|
-
if (stopped)
|
|
113511
|
+
if (stopped || observed == null)
|
|
113280
113512
|
return;
|
|
113281
|
-
handleObservedChange(observed
|
|
113513
|
+
handleObservedChange(observed);
|
|
113282
113514
|
}, (err) => {
|
|
113283
113515
|
console.warn(`[${formatTimestamp()}] ⚠️ Observed-sync subscription error: ${getErrorMessage(err)}`);
|
|
113284
113516
|
});
|
|
@@ -113291,8 +113523,8 @@ var startObservedSyncSubscriptionEffect = (wsClient2) => exports_Effect.gen(func
|
|
|
113291
113523
|
sessionId: session2.sessionId,
|
|
113292
113524
|
machineId: session2.machineId
|
|
113293
113525
|
}).then((observed) => {
|
|
113294
|
-
if (!stopped)
|
|
113295
|
-
handleObservedChange(observed
|
|
113526
|
+
if (!stopped && observed != null)
|
|
113527
|
+
handleObservedChange(observed);
|
|
113296
113528
|
}).catch((err) => {
|
|
113297
113529
|
console.warn(`[${formatTimestamp()}] ⚠️ Observed-sync reconcile query failed: ${getErrorMessage(err)}`);
|
|
113298
113530
|
}).finally(() => {
|
|
@@ -114501,8 +114733,8 @@ var init_task_monitor = __esm(() => {
|
|
|
114501
114733
|
});
|
|
114502
114734
|
|
|
114503
114735
|
// src/commands/machine/daemon-start/workspace-list-subscription.ts
|
|
114504
|
-
function toSyncWorkspaces(
|
|
114505
|
-
return
|
|
114736
|
+
function toSyncWorkspaces(workingDirs) {
|
|
114737
|
+
return workingDirs.map((workingDir) => ({ workingDir }));
|
|
114506
114738
|
}
|
|
114507
114739
|
var startWorkspaceListSubscriptionEffect = (wsClient2) => exports_Effect.gen(function* () {
|
|
114508
114740
|
const session2 = yield* DaemonSessionService;
|
|
@@ -114514,16 +114746,16 @@ var startWorkspaceListSubscriptionEffect = (wsClient2) => exports_Effect.gen(fun
|
|
|
114514
114746
|
};
|
|
114515
114747
|
let stopped = false;
|
|
114516
114748
|
let reconcileInFlight = false;
|
|
114517
|
-
const applyList = (
|
|
114749
|
+
const applyList = (workingDirs) => {
|
|
114518
114750
|
if (!session2.workspaceListStore)
|
|
114519
114751
|
return;
|
|
114520
|
-
session2.workspaceListStore.workspaces = toSyncWorkspaces(
|
|
114752
|
+
session2.workspaceListStore.workspaces = toSyncWorkspaces(workingDirs);
|
|
114521
114753
|
session2.workspaceListStore.updatedAt = Date.now();
|
|
114522
114754
|
};
|
|
114523
114755
|
const unsubscribe = wsClient2.onUpdate(api.workspaces.listRecentlyObservedWorkspacesForMachine, queryArgs, (workspaces) => {
|
|
114524
|
-
if (stopped)
|
|
114756
|
+
if (stopped || workspaces == null)
|
|
114525
114757
|
return;
|
|
114526
|
-
applyList(workspaces
|
|
114758
|
+
applyList(workspaces);
|
|
114527
114759
|
}, (err) => {
|
|
114528
114760
|
console.warn(`[${formatTimestamp()}] ⚠️ Workspace-list subscription error: ${getErrorMessage(err)}`);
|
|
114529
114761
|
});
|
|
@@ -114532,8 +114764,8 @@ var startWorkspaceListSubscriptionEffect = (wsClient2) => exports_Effect.gen(fun
|
|
|
114532
114764
|
return;
|
|
114533
114765
|
reconcileInFlight = true;
|
|
114534
114766
|
session2.backend.query(api.workspaces.listRecentlyObservedWorkspacesForMachine, queryArgs).then((workspaces) => {
|
|
114535
|
-
if (!stopped)
|
|
114536
|
-
applyList(workspaces
|
|
114767
|
+
if (!stopped && workspaces != null)
|
|
114768
|
+
applyList(workspaces);
|
|
114537
114769
|
}).catch((err) => {
|
|
114538
114770
|
console.warn(`[${formatTimestamp()}] ⚠️ Workspace-list reconcile failed: ${getErrorMessage(err)}`);
|
|
114539
114771
|
}).finally(() => {
|
|
@@ -116147,4 +116379,4 @@ program2.hook("preAction", async (_thisCommand, actionCommand) => {
|
|
|
116147
116379
|
});
|
|
116148
116380
|
program2.parse();
|
|
116149
116381
|
|
|
116150
|
-
//# debugId=
|
|
116382
|
+
//# debugId=550B12123AE171BD64756E2164756E21
|