mancode 0.6.5 → 0.6.6
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.en.md +80 -37
- package/README.md +52 -21
- package/dist/{chunk-E2K22WYH.js → chunk-D5ABGAF4.js} +164 -70
- package/dist/{chunk-E2K22WYH.js.map → chunk-D5ABGAF4.js.map} +1 -1
- package/dist/{chunk-WJ6WARGG.js → chunk-RMHUYJXB.js} +46 -47
- package/dist/chunk-RMHUYJXB.js.map +1 -0
- package/dist/cli.js +608 -442
- package/dist/cli.js.map +1 -1
- package/dist/{store-GSLSLZ7D.js → store-LLXL7QYG.js} +2 -2
- package/dist/{v3-adapter-T3IKK3LU.js → v3-adapter-KA2NOVI5.js} +2 -2
- package/package.json +3 -2
- package/dist/chunk-WJ6WARGG.js.map +0 -1
- /package/dist/{store-GSLSLZ7D.js.map → store-LLXL7QYG.js.map} +0 -0
- /package/dist/{v3-adapter-T3IKK3LU.js.map → v3-adapter-KA2NOVI5.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -37,6 +37,7 @@ import {
|
|
|
37
37
|
assertSharedPrivacyValue,
|
|
38
38
|
assertSharedTaskWriteAtRoot,
|
|
39
39
|
assertSharedTextSafe,
|
|
40
|
+
assertSoloHandoffSession,
|
|
40
41
|
assertTaskCompletionGate,
|
|
41
42
|
assertTaskHeadFenceMatchesAggregate,
|
|
42
43
|
assertTaskHeadFenceTransition,
|
|
@@ -60,6 +61,7 @@ import {
|
|
|
60
61
|
gitRefWorkflowRepairJournalPath,
|
|
61
62
|
hasProjectEvidence,
|
|
62
63
|
implementationScopeIsExecutable,
|
|
64
|
+
isActiveSoloHandoff,
|
|
63
65
|
isPrivacyExcluded,
|
|
64
66
|
listGitRefWorkflowRepairJournalSummaries,
|
|
65
67
|
listUnfinishedGitRefWorkflowRepairs,
|
|
@@ -103,6 +105,7 @@ import {
|
|
|
103
105
|
readPrivacyAuthorityFile,
|
|
104
106
|
readPrivacyPolicySnapshot,
|
|
105
107
|
readPrivacyPolicyStatus,
|
|
108
|
+
redactSharedText,
|
|
106
109
|
removeOperationReservation,
|
|
107
110
|
replaceFileAtomically,
|
|
108
111
|
requirementsAreReady,
|
|
@@ -120,7 +123,7 @@ import {
|
|
|
120
123
|
withSharedPrivacyWrite,
|
|
121
124
|
workflowMetadataDigest,
|
|
122
125
|
writeProjectFacts
|
|
123
|
-
} from "./chunk-
|
|
126
|
+
} from "./chunk-D5ABGAF4.js";
|
|
124
127
|
import {
|
|
125
128
|
ACCEPTED_STATE_NARRATIVE_GUIDANCE,
|
|
126
129
|
DEFAULT_MANCODE_END_MARKER,
|
|
@@ -149,7 +152,7 @@ import {
|
|
|
149
152
|
v3AdapterTargetPath,
|
|
150
153
|
v3AdapterVersionsFromStatuses,
|
|
151
154
|
writeThroughResolvedPath
|
|
152
|
-
} from "./chunk-
|
|
155
|
+
} from "./chunk-RMHUYJXB.js";
|
|
153
156
|
import {
|
|
154
157
|
readPrivacyGatewayStatus,
|
|
155
158
|
registerPrivacyGatewayCommands
|
|
@@ -4746,6 +4749,9 @@ async function clearSessionTaskPointer(projectRoot, sessionId, input = {}) {
|
|
|
4746
4749
|
if (expected !== void 0 && (session.activeTaskRef === null || session.activeTaskRef.namespace !== expected.namespace || session.activeTaskRef.taskId !== expected.taskId)) {
|
|
4747
4750
|
return session;
|
|
4748
4751
|
}
|
|
4752
|
+
if (input.isStillApplicable && !await input.isStillApplicable()) {
|
|
4753
|
+
return session;
|
|
4754
|
+
}
|
|
4749
4755
|
const updated = {
|
|
4750
4756
|
...session,
|
|
4751
4757
|
activeTaskRef: null,
|
|
@@ -7953,8 +7959,12 @@ function buildContextPack(input) {
|
|
|
7953
7959
|
omissions.push(omissionFor(section, "privacy"));
|
|
7954
7960
|
continue;
|
|
7955
7961
|
}
|
|
7956
|
-
|
|
7957
|
-
section
|
|
7962
|
+
const projected = projectGovernanceLocalPaths(
|
|
7963
|
+
section,
|
|
7964
|
+
input.privacy?.policy.enabled ? input.privacy.policy.enabledRuleIds : void 0
|
|
7965
|
+
);
|
|
7966
|
+
if (containsSensitiveText(projected.value) || input.privacy?.policy.enabled && containsEnhancedSensitiveText(
|
|
7967
|
+
projected.value,
|
|
7958
7968
|
input.privacy.policy.enabledRuleIds
|
|
7959
7969
|
)) {
|
|
7960
7970
|
omissions.push(omissionFor(section, "privacy"));
|
|
@@ -7963,7 +7973,7 @@ function buildContextPack(input) {
|
|
|
7963
7973
|
}
|
|
7964
7974
|
continue;
|
|
7965
7975
|
}
|
|
7966
|
-
included.set(pointer,
|
|
7976
|
+
included.set(pointer, projected);
|
|
7967
7977
|
}
|
|
7968
7978
|
while (true) {
|
|
7969
7979
|
const candidate = assemblePack(input, included, omissions, false, 0);
|
|
@@ -8138,6 +8148,90 @@ function containsSensitiveText(value) {
|
|
|
8138
8148
|
}
|
|
8139
8149
|
return false;
|
|
8140
8150
|
}
|
|
8151
|
+
function projectGovernanceLocalPaths(section, enhancedRuleIds) {
|
|
8152
|
+
if (!isRequiredSection(section) || !isRecord3(section.value)) return section;
|
|
8153
|
+
const original = section.value;
|
|
8154
|
+
const redactions = [];
|
|
8155
|
+
const projectText = (value2, pointer, command = false) => {
|
|
8156
|
+
const findings = scanSharedText(value2);
|
|
8157
|
+
if (findings.length === 0 || findings.some((finding) => finding.kind !== "absolute_path")) {
|
|
8158
|
+
return value2;
|
|
8159
|
+
}
|
|
8160
|
+
const text = redactSharedText(value2).text;
|
|
8161
|
+
if (enhancedRuleIds !== void 0 && containsEnhancedSensitiveText(text, enhancedRuleIds)) {
|
|
8162
|
+
return value2;
|
|
8163
|
+
}
|
|
8164
|
+
const target = `${section.targetJsonPointer}${pointer}`;
|
|
8165
|
+
redactions.push(`${target}:absolute_path`);
|
|
8166
|
+
if (command) {
|
|
8167
|
+
redactions.push(`${target}:command_omitted_not_executable`);
|
|
8168
|
+
return "[REDACTED:non_executable_command]";
|
|
8169
|
+
}
|
|
8170
|
+
return text;
|
|
8171
|
+
};
|
|
8172
|
+
let value;
|
|
8173
|
+
if (section.targetJsonPointer === "/governance/requirements") {
|
|
8174
|
+
value = { ...original };
|
|
8175
|
+
if (Array.isArray(original.technicalDecisions)) {
|
|
8176
|
+
value.technicalDecisions = original.technicalDecisions.map(
|
|
8177
|
+
(decision, index) => isRecord3(decision) && typeof decision.statement === "string" ? {
|
|
8178
|
+
...decision,
|
|
8179
|
+
statement: projectText(
|
|
8180
|
+
decision.statement,
|
|
8181
|
+
`/technicalDecisions/${index}/statement`
|
|
8182
|
+
)
|
|
8183
|
+
} : decision
|
|
8184
|
+
);
|
|
8185
|
+
}
|
|
8186
|
+
if (isRecord3(original.functionalScope) && Array.isArray(original.functionalScope.outOfScope)) {
|
|
8187
|
+
value.functionalScope = {
|
|
8188
|
+
...original.functionalScope,
|
|
8189
|
+
outOfScope: original.functionalScope.outOfScope.map(
|
|
8190
|
+
(entry, index) => typeof entry === "string" ? projectText(entry, `/functionalScope/outOfScope/${index}`) : entry
|
|
8191
|
+
)
|
|
8192
|
+
};
|
|
8193
|
+
}
|
|
8194
|
+
} else if (section.targetJsonPointer === "/governance/review" && isRecord3(original.delivery) && typeof original.delivery.correctness === "string") {
|
|
8195
|
+
value = {
|
|
8196
|
+
...original,
|
|
8197
|
+
delivery: {
|
|
8198
|
+
...original.delivery,
|
|
8199
|
+
correctness: projectText(
|
|
8200
|
+
original.delivery.correctness,
|
|
8201
|
+
"/delivery/correctness"
|
|
8202
|
+
)
|
|
8203
|
+
}
|
|
8204
|
+
};
|
|
8205
|
+
} else if (section.targetJsonPointer === "/governance/verification" && Array.isArray(original.checks)) {
|
|
8206
|
+
value = {
|
|
8207
|
+
...original,
|
|
8208
|
+
checks: original.checks.map(
|
|
8209
|
+
(check, index) => isRecord3(check) && isRecord3(check.automated) && typeof check.automated.command === "string" ? {
|
|
8210
|
+
...check,
|
|
8211
|
+
automated: {
|
|
8212
|
+
...check.automated,
|
|
8213
|
+
command: projectText(
|
|
8214
|
+
check.automated.command,
|
|
8215
|
+
`/checks/${index}/automated/command`,
|
|
8216
|
+
true
|
|
8217
|
+
)
|
|
8218
|
+
}
|
|
8219
|
+
} : check
|
|
8220
|
+
)
|
|
8221
|
+
};
|
|
8222
|
+
} else {
|
|
8223
|
+
return section;
|
|
8224
|
+
}
|
|
8225
|
+
if (redactions.length === 0) return section;
|
|
8226
|
+
return {
|
|
8227
|
+
...section,
|
|
8228
|
+
value,
|
|
8229
|
+
provenance: section.provenance.map((entry) => ({
|
|
8230
|
+
...entry,
|
|
8231
|
+
redactions: [.../* @__PURE__ */ new Set([...entry.redactions, ...redactions])].sort()
|
|
8232
|
+
}))
|
|
8233
|
+
};
|
|
8234
|
+
}
|
|
8141
8235
|
function assertBuildInput(input) {
|
|
8142
8236
|
assertTimestamp(input.generatedAt, "context pack generatedAt");
|
|
8143
8237
|
assertContextLevel(input.level);
|
|
@@ -10759,7 +10853,7 @@ async function activateLegacyMigration(input) {
|
|
|
10759
10853
|
if (session === null || session.status !== "active") {
|
|
10760
10854
|
throw new Error("MANCODE_SESSION_NOT_FOUND");
|
|
10761
10855
|
}
|
|
10762
|
-
const store = new (await import("./store-
|
|
10856
|
+
const store = new (await import("./store-LLXL7QYG.js")).V3ContextStore(root);
|
|
10763
10857
|
const project = await store.readProjectSnapshot();
|
|
10764
10858
|
const stage = await readMigrationStage(root, input.stageId);
|
|
10765
10859
|
if (stage.state !== "staged" || stage.revision !== input.expectedStageRevision) {
|
|
@@ -11033,7 +11127,7 @@ async function activateLegacyMigration(input) {
|
|
|
11033
11127
|
for (const action of payload.actions.filter(
|
|
11034
11128
|
(action2) => action2.kind === "v3_adapter_file"
|
|
11035
11129
|
)) {
|
|
11036
|
-
const { applyV3AdapterFilePlan: applyV3AdapterFilePlan2 } = await import("./v3-adapter-
|
|
11130
|
+
const { applyV3AdapterFilePlan: applyV3AdapterFilePlan2 } = await import("./v3-adapter-KA2NOVI5.js");
|
|
11037
11131
|
await applyV3AdapterFilePlan2(root, action);
|
|
11038
11132
|
}
|
|
11039
11133
|
journal = await completeActivationStep(
|
|
@@ -14711,7 +14805,7 @@ async function inspectOperationProjectionState(projectRoot, operationId) {
|
|
|
14711
14805
|
});
|
|
14712
14806
|
for (const intent of intents) {
|
|
14713
14807
|
const key = projectionStateKey(intent.target.kind);
|
|
14714
|
-
const availability = intent.state === "superseded" ? "not_applicable" : await inspectProjection(projectRoot, intent.target);
|
|
14808
|
+
const availability = intent.state === "superseded" || intent.state === "completed" && intent.target.kind === "session_pointer" ? "not_applicable" : await inspectProjection(projectRoot, intent.target);
|
|
14715
14809
|
state[key] = mergeProjectionAvailability(state[key], availability);
|
|
14716
14810
|
}
|
|
14717
14811
|
return state;
|
|
@@ -15009,12 +15103,20 @@ async function inspectSessionProjection(projectRoot, target) {
|
|
|
15009
15103
|
if (task.metadata.revision < target.taskRevision) return "conflict";
|
|
15010
15104
|
const clearsPointer = workflowRequiresClearedSession(task.metadata);
|
|
15011
15105
|
if (target.action === "clear") {
|
|
15012
|
-
if (!clearsPointer)
|
|
15106
|
+
if (!clearsPointer) {
|
|
15107
|
+
return task.metadata.revision > target.taskRevision ? "not_applicable" : "conflict";
|
|
15108
|
+
}
|
|
15013
15109
|
if (session.activeTaskRef === null) return "present";
|
|
15110
|
+
if (task.metadata.status === "planned" && task.metadata.governance.planDecision === "plan_only" && sameTaskRef(session.activeTaskRef, target.taskRef) && session.lastSeenRevision !== null && session.lastSeenRevision >= target.taskRevision) {
|
|
15111
|
+
return "not_applicable";
|
|
15112
|
+
}
|
|
15014
15113
|
return sameTaskRef(session.activeTaskRef, target.taskRef) ? "missing" : "not_applicable";
|
|
15015
15114
|
}
|
|
15016
15115
|
if (clearsPointer) {
|
|
15017
15116
|
if (session.activeTaskRef === null) return "not_applicable";
|
|
15117
|
+
if (task.metadata.status === "planned" && task.metadata.governance.planDecision === "plan_only" && sameTaskRef(session.activeTaskRef, target.taskRef) && session.lastSeenRevision !== null && session.lastSeenRevision >= task.metadata.revision) {
|
|
15118
|
+
return "not_applicable";
|
|
15119
|
+
}
|
|
15018
15120
|
return sameTaskRef(session.activeTaskRef, target.taskRef) ? "missing" : "not_applicable";
|
|
15019
15121
|
}
|
|
15020
15122
|
if (session.activeTaskRef !== null && sameTaskRef(session.activeTaskRef, target.taskRef)) {
|
|
@@ -15035,6 +15137,10 @@ async function applySessionProjection(projectRoot, target, now) {
|
|
|
15035
15137
|
if (target.action === "clear" || workflowRequiresClearedSession(task.metadata)) {
|
|
15036
15138
|
await clearSessionTaskPointer(projectRoot, target.sessionId, {
|
|
15037
15139
|
expectedTaskRef: target.taskRef,
|
|
15140
|
+
isStillApplicable: async () => {
|
|
15141
|
+
const current = await readProjectionTask(projectRoot, target.taskRef);
|
|
15142
|
+
return current !== null && workflowRequiresClearedSession(current.metadata) && await inspectSessionProjection(projectRoot, target) === "missing";
|
|
15143
|
+
},
|
|
15038
15144
|
now
|
|
15039
15145
|
});
|
|
15040
15146
|
return;
|
|
@@ -16636,7 +16742,7 @@ async function upgradeV3Adapters(input) {
|
|
|
16636
16742
|
if (unfinished.length > 0) {
|
|
16637
16743
|
throw new Error("MANCODE_ADAPTER_UPGRADE_OPERATION_PENDING");
|
|
16638
16744
|
}
|
|
16639
|
-
const actualVersions = await import("./v3-adapter-
|
|
16745
|
+
const actualVersions = await import("./v3-adapter-KA2NOVI5.js").then(
|
|
16640
16746
|
({ inspectV3AdapterVersions: inspectV3AdapterVersions2 }) => inspectV3AdapterVersions2(
|
|
16641
16747
|
root,
|
|
16642
16748
|
managedAdapterNames(project.manifest.managedAdapters)
|
|
@@ -23443,10 +23549,11 @@ function compareUtf89(left, right) {
|
|
|
23443
23549
|
|
|
23444
23550
|
// src/context/task-head-reconcile.ts
|
|
23445
23551
|
import { execFile as execFileCallback3 } from "child_process";
|
|
23446
|
-
import
|
|
23552
|
+
import path40 from "path";
|
|
23447
23553
|
import { promisify as promisify3 } from "util";
|
|
23448
23554
|
|
|
23449
23555
|
// src/team/conflicts.ts
|
|
23556
|
+
import path39 from "path";
|
|
23450
23557
|
function deriveClaimValidity(claim, context) {
|
|
23451
23558
|
assertClaimValidationContext(context);
|
|
23452
23559
|
if (claim.state !== "active") return "inactive";
|
|
@@ -23570,6 +23677,8 @@ function hasPotentialPathIntersection(left, right) {
|
|
|
23570
23677
|
}
|
|
23571
23678
|
function isPathSubsetOf(candidate, boundary) {
|
|
23572
23679
|
if (candidate === boundary) return true;
|
|
23680
|
+
if (containsComplexGlob(candidate) || containsComplexGlob(boundary))
|
|
23681
|
+
return false;
|
|
23573
23682
|
const candidatePrefix = staticPathPrefix(candidate);
|
|
23574
23683
|
const boundaryPrefix = staticPathPrefix(boundary);
|
|
23575
23684
|
if (!candidatePrefix.startsWith(boundaryPrefix)) return false;
|
|
@@ -23578,17 +23687,29 @@ function isPathSubsetOf(candidate, boundary) {
|
|
|
23578
23687
|
}
|
|
23579
23688
|
function globPatternsMayOverlap(left, right) {
|
|
23580
23689
|
if (left === right) return true;
|
|
23690
|
+
const leftIsGlob = containsGlob(left);
|
|
23691
|
+
const rightIsGlob = containsGlob(right);
|
|
23692
|
+
if (!leftIsGlob && !rightIsGlob) return false;
|
|
23693
|
+
if (!leftIsGlob && !containsComplexGlob(right)) {
|
|
23694
|
+
return path39.posix.matchesGlob(left, right);
|
|
23695
|
+
}
|
|
23696
|
+
if (!rightIsGlob && !containsComplexGlob(left)) {
|
|
23697
|
+
return path39.posix.matchesGlob(right, left);
|
|
23698
|
+
}
|
|
23581
23699
|
const leftPrefix = staticPathPrefix(left);
|
|
23582
23700
|
const rightPrefix = staticPathPrefix(right);
|
|
23583
23701
|
return leftPrefix.startsWith(rightPrefix) || rightPrefix.startsWith(leftPrefix);
|
|
23584
23702
|
}
|
|
23585
23703
|
function staticPathPrefix(value) {
|
|
23586
|
-
const wildcard = value.search(/[*!?\[]/);
|
|
23704
|
+
const wildcard = value.search(/[*!?\[\]{}()]/);
|
|
23587
23705
|
const prefix = wildcard === -1 ? value : value.slice(0, wildcard);
|
|
23588
23706
|
return prefix.endsWith("/") ? prefix : prefix.slice(0, prefix.lastIndexOf("/") + 1);
|
|
23589
23707
|
}
|
|
23590
23708
|
function containsGlob(value) {
|
|
23591
|
-
return /[*!?\[]/.test(value);
|
|
23709
|
+
return /[*!?\[\]{}()]/.test(value);
|
|
23710
|
+
}
|
|
23711
|
+
function containsComplexGlob(value) {
|
|
23712
|
+
return /[!\[\]{}()]/.test(value);
|
|
23592
23713
|
}
|
|
23593
23714
|
function hasIntersection(left, right) {
|
|
23594
23715
|
return left.some((value) => right.includes(value));
|
|
@@ -23871,8 +23992,8 @@ function injectAfterReconcileStep(stepId) {
|
|
|
23871
23992
|
throwIfOperationCrashInjected("task_head_reconcile", stepId);
|
|
23872
23993
|
}
|
|
23873
23994
|
async function assertGitSourcedTaskAggregate(projectRoot, taskRoot2) {
|
|
23874
|
-
const relativeTaskRoot =
|
|
23875
|
-
if (!relativeTaskRoot ||
|
|
23995
|
+
const relativeTaskRoot = path40.relative(projectRoot, taskRoot2);
|
|
23996
|
+
if (!relativeTaskRoot || path40.isAbsolute(relativeTaskRoot) || relativeTaskRoot.split(path40.sep).some((part) => part === "..")) {
|
|
23876
23997
|
throw new Error("MANCODE_TASK_UNAVAILABLE");
|
|
23877
23998
|
}
|
|
23878
23999
|
const authorityFiles = [
|
|
@@ -23880,7 +24001,7 @@ async function assertGitSourcedTaskAggregate(projectRoot, taskRoot2) {
|
|
|
23880
24001
|
"requirements.json",
|
|
23881
24002
|
"review-ledger.json",
|
|
23882
24003
|
"verification-ledger.json"
|
|
23883
|
-
].map((file) =>
|
|
24004
|
+
].map((file) => path40.join(relativeTaskRoot, file));
|
|
23884
24005
|
try {
|
|
23885
24006
|
await execFile3("git", ["rev-parse", "--verify", "HEAD^{commit}"], {
|
|
23886
24007
|
cwd: projectRoot,
|
|
@@ -24106,11 +24227,11 @@ var BETA_PLATFORMS = [
|
|
|
24106
24227
|
|
|
24107
24228
|
// src/runtime/retention.ts
|
|
24108
24229
|
import { lstat as lstat14, readFile as readFile28, readdir as readdir13, rm as rm17 } from "fs/promises";
|
|
24109
|
-
import
|
|
24230
|
+
import path41 from "path";
|
|
24110
24231
|
var TERMINAL_JOURNAL_RETENTION_DAYS = 30;
|
|
24111
24232
|
var RETAINED_NON_MILESTONE_CHECKPOINTS = 10;
|
|
24112
24233
|
async function planContextCompaction(input) {
|
|
24113
|
-
const root =
|
|
24234
|
+
const root = path41.resolve(input.projectRoot);
|
|
24114
24235
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
24115
24236
|
const store = new V3ContextStore(root);
|
|
24116
24237
|
const [project, runtime] = await Promise.all([
|
|
@@ -24170,7 +24291,7 @@ async function planContextCompaction(input) {
|
|
|
24170
24291
|
}
|
|
24171
24292
|
async function planLocalCacheRetention(root, localCacheDays, now) {
|
|
24172
24293
|
const threshold = now.getTime() - localCacheDays * 864e5;
|
|
24173
|
-
const directory =
|
|
24294
|
+
const directory = path41.join(root, ".mancode", "local", "cache");
|
|
24174
24295
|
const candidates = [];
|
|
24175
24296
|
for (const target of await listRegularFilesRecursively(directory)) {
|
|
24176
24297
|
const metadata = await regularFileMetadataOrNull(target);
|
|
@@ -24233,7 +24354,7 @@ async function planCheckpointCompaction(store, coordinationStore, taskRefs, prot
|
|
|
24233
24354
|
}
|
|
24234
24355
|
candidates.push({
|
|
24235
24356
|
kind: "checkpoint",
|
|
24236
|
-
target:
|
|
24357
|
+
target: path41.join(
|
|
24237
24358
|
task.location.taskRoot,
|
|
24238
24359
|
"checkpoints",
|
|
24239
24360
|
`${checkpoint.checkpointId}.json`
|
|
@@ -24247,13 +24368,13 @@ async function planCheckpointCompaction(store, coordinationStore, taskRefs, prot
|
|
|
24247
24368
|
return { candidates, skippedReferencedCheckpoints };
|
|
24248
24369
|
}
|
|
24249
24370
|
async function planCompletedSessionRetention(root, completedSessionDays, now, protectedSessionIds) {
|
|
24250
|
-
const directory =
|
|
24371
|
+
const directory = path41.join(root, ".mancode", "local", "sessions");
|
|
24251
24372
|
const entries = await readDirectoryOrEmpty(directory);
|
|
24252
24373
|
const threshold = now.getTime() - completedSessionDays * 864e5;
|
|
24253
24374
|
const candidates = [];
|
|
24254
24375
|
for (const entry of entries) {
|
|
24255
24376
|
if (!entry.endsWith(".json")) continue;
|
|
24256
|
-
const target =
|
|
24377
|
+
const target = path41.join(directory, entry);
|
|
24257
24378
|
const session = parseSessionState(
|
|
24258
24379
|
JSON.parse(await readRegularFile(target))
|
|
24259
24380
|
);
|
|
@@ -24280,7 +24401,7 @@ async function planOperationRetention(stores, now) {
|
|
|
24280
24401
|
let recoveryEntries = null;
|
|
24281
24402
|
for (const entry of entries) {
|
|
24282
24403
|
if (!entry.endsWith(".json")) continue;
|
|
24283
|
-
const target =
|
|
24404
|
+
const target = path41.join(directory, entry);
|
|
24284
24405
|
const journal = parseOperationJournal(
|
|
24285
24406
|
JSON.parse(await readRegularFile(target))
|
|
24286
24407
|
);
|
|
@@ -24349,7 +24470,7 @@ function operationRecoveryTargetsForRetention(store, journal, recoveryEntries) {
|
|
|
24349
24470
|
const discoveredVersions = recoveryEntries.filter((entry) => {
|
|
24350
24471
|
if (!entry.startsWith(versionPrefix)) return false;
|
|
24351
24472
|
return /^[a-f0-9]{64}\.json$/.test(entry.slice(versionPrefix.length));
|
|
24352
|
-
}).map((entry) =>
|
|
24473
|
+
}).map((entry) => path41.join(directory, entry));
|
|
24353
24474
|
return [
|
|
24354
24475
|
.../* @__PURE__ */ new Set([
|
|
24355
24476
|
operationRecoveryPayloadPath(store, journal.operationId),
|
|
@@ -24384,7 +24505,7 @@ function taskRefKeyFromEntityKey(entityKey) {
|
|
|
24384
24505
|
async function listTaskRefs(root) {
|
|
24385
24506
|
const refs = [];
|
|
24386
24507
|
for (const namespace of ["local", "shared"]) {
|
|
24387
|
-
const directory =
|
|
24508
|
+
const directory = path41.join(root, ".mancode", namespace, "workflows");
|
|
24388
24509
|
for (const entry of await readDirectoryOrEmpty(directory)) {
|
|
24389
24510
|
if (!/^[0-9A-HJKMNP-TV-Z]{26}$/.test(entry)) continue;
|
|
24390
24511
|
refs.push({ namespace, taskId: entry });
|
|
@@ -24397,12 +24518,12 @@ async function listTaskRefs(root) {
|
|
|
24397
24518
|
);
|
|
24398
24519
|
}
|
|
24399
24520
|
async function listTaskCheckpoints(taskRoot2, taskRef) {
|
|
24400
|
-
const directory =
|
|
24521
|
+
const directory = path41.join(taskRoot2, "checkpoints");
|
|
24401
24522
|
const checkpoints = [];
|
|
24402
24523
|
for (const entry of await readDirectoryOrEmpty(directory)) {
|
|
24403
24524
|
if (!entry.endsWith(".json")) continue;
|
|
24404
24525
|
const checkpoint = parseCheckpoint(
|
|
24405
|
-
JSON.parse(await readRegularFile(
|
|
24526
|
+
JSON.parse(await readRegularFile(path41.join(directory, entry)))
|
|
24406
24527
|
);
|
|
24407
24528
|
if (!sameTaskRef(checkpoint.taskRef, taskRef) || entry !== `${checkpoint.checkpointId}.json`) {
|
|
24408
24529
|
throw new Error("MANCODE_RETENTION_CHECKPOINT_CORRUPT");
|
|
@@ -24441,7 +24562,7 @@ async function readDirectoryOrEmpty(directory) {
|
|
|
24441
24562
|
async function listRegularFilesRecursively(directory) {
|
|
24442
24563
|
const files = [];
|
|
24443
24564
|
for (const entry of await readDirectoryOrEmpty(directory)) {
|
|
24444
|
-
const target =
|
|
24565
|
+
const target = path41.join(directory, entry);
|
|
24445
24566
|
const metadata = await lstatOrNull3(target);
|
|
24446
24567
|
if (metadata === null) continue;
|
|
24447
24568
|
if (metadata.isSymbolicLink()) {
|
|
@@ -24506,7 +24627,7 @@ function isNotFound19(error) {
|
|
|
24506
24627
|
|
|
24507
24628
|
// src/team/git-ref-cache.ts
|
|
24508
24629
|
import { lstat as lstat15, mkdir as mkdir26, readFile as readFile29, writeFile as writeFile34 } from "fs/promises";
|
|
24509
|
-
import
|
|
24630
|
+
import path42 from "path";
|
|
24510
24631
|
var DEFAULT_GIT_REF_FRESHNESS_TTL_MS = 5 * 60 * 1e3;
|
|
24511
24632
|
async function writeGitRefTeamCache(projectRoot, config, snapshot) {
|
|
24512
24633
|
const remote = gitRefRemote(config);
|
|
@@ -24524,7 +24645,7 @@ async function writeGitRefTeamCache(projectRoot, config, snapshot) {
|
|
|
24524
24645
|
await assertCachePrivacyAuthority(projectRoot, cache.manifest);
|
|
24525
24646
|
const directory = await ensureSafeCacheDirectory(projectRoot);
|
|
24526
24647
|
const target = gitRefCachePath(projectRoot);
|
|
24527
|
-
const temporary =
|
|
24648
|
+
const temporary = path42.join(
|
|
24528
24649
|
directory,
|
|
24529
24650
|
`.snapshot.${process.pid}.${Date.now()}.tmp`
|
|
24530
24651
|
);
|
|
@@ -24656,11 +24777,11 @@ function parseGitRefTeamCache(value) {
|
|
|
24656
24777
|
};
|
|
24657
24778
|
}
|
|
24658
24779
|
function gitRefCachePath(projectRoot) {
|
|
24659
|
-
return
|
|
24780
|
+
return path42.join(gitRefCacheDirectory(projectRoot), "snapshot.json");
|
|
24660
24781
|
}
|
|
24661
24782
|
function gitRefCacheDirectory(projectRoot) {
|
|
24662
|
-
return
|
|
24663
|
-
|
|
24783
|
+
return path42.join(
|
|
24784
|
+
path42.resolve(projectRoot),
|
|
24664
24785
|
".mancode",
|
|
24665
24786
|
"local",
|
|
24666
24787
|
"cache",
|
|
@@ -24706,10 +24827,10 @@ function parseReceiptOrNull(value) {
|
|
|
24706
24827
|
return value;
|
|
24707
24828
|
}
|
|
24708
24829
|
async function ensureSafeCacheDirectory(projectRoot) {
|
|
24709
|
-
const root =
|
|
24830
|
+
const root = path42.resolve(projectRoot);
|
|
24710
24831
|
let current = root;
|
|
24711
24832
|
for (const segment of [".mancode", "local", "cache", "git-ref"]) {
|
|
24712
|
-
current =
|
|
24833
|
+
current = path42.join(current, segment);
|
|
24713
24834
|
try {
|
|
24714
24835
|
await mkdir26(current);
|
|
24715
24836
|
} catch (error) {
|
|
@@ -24720,9 +24841,9 @@ async function ensureSafeCacheDirectory(projectRoot) {
|
|
|
24720
24841
|
return current;
|
|
24721
24842
|
}
|
|
24722
24843
|
async function assertSafeCacheDirectory(projectRoot) {
|
|
24723
|
-
let current =
|
|
24844
|
+
let current = path42.resolve(projectRoot);
|
|
24724
24845
|
for (const segment of [".mancode", "local", "cache", "git-ref"]) {
|
|
24725
|
-
current =
|
|
24846
|
+
current = path42.join(current, segment);
|
|
24726
24847
|
await assertDirectoryNotLinked(current);
|
|
24727
24848
|
}
|
|
24728
24849
|
}
|
|
@@ -24741,7 +24862,7 @@ function isAlreadyExists14(error) {
|
|
|
24741
24862
|
|
|
24742
24863
|
// src/team/git-ref-workflow-repair.ts
|
|
24743
24864
|
import { lstat as lstat19, mkdir as mkdir30, readFile as readFile33, readdir as readdir16, writeFile as writeFile38 } from "fs/promises";
|
|
24744
|
-
import
|
|
24865
|
+
import path46 from "path";
|
|
24745
24866
|
|
|
24746
24867
|
// src/team/git-ref-materialization.ts
|
|
24747
24868
|
import {
|
|
@@ -24752,12 +24873,12 @@ import {
|
|
|
24752
24873
|
unlink as unlink2,
|
|
24753
24874
|
writeFile as writeFile37
|
|
24754
24875
|
} from "fs/promises";
|
|
24755
|
-
import
|
|
24876
|
+
import path45 from "path";
|
|
24756
24877
|
|
|
24757
24878
|
// src/team/git-ref-bundle.ts
|
|
24758
24879
|
import { execFile as execFileCallback4 } from "child_process";
|
|
24759
24880
|
import { lstat as lstat16, mkdir as mkdir27, readFile as readFile30, readdir as readdir14, writeFile as writeFile35 } from "fs/promises";
|
|
24760
|
-
import
|
|
24881
|
+
import path43 from "path";
|
|
24761
24882
|
import { promisify as promisify4 } from "util";
|
|
24762
24883
|
var execFile4 = promisify4(execFileCallback4);
|
|
24763
24884
|
function createGitRefTaskBundle(input) {
|
|
@@ -24820,7 +24941,7 @@ async function assertGitRefBundleCodeReachable(projectRoot, bundle) {
|
|
|
24820
24941
|
"git",
|
|
24821
24942
|
["cat-file", "-e", `${parsed.codeRef.head}^{commit}`],
|
|
24822
24943
|
{
|
|
24823
|
-
cwd:
|
|
24944
|
+
cwd: path43.resolve(projectRoot),
|
|
24824
24945
|
windowsHide: true
|
|
24825
24946
|
}
|
|
24826
24947
|
);
|
|
@@ -24833,8 +24954,8 @@ async function quarantineGitRefTaskBundle(projectRoot, remoteRevision, bundle) {
|
|
|
24833
24954
|
throw new Error("MANCODE_TRANSPORT_REVISION_INVALID");
|
|
24834
24955
|
}
|
|
24835
24956
|
const parsed = parseGitRefTaskBundle(bundle);
|
|
24836
|
-
const directory =
|
|
24837
|
-
|
|
24957
|
+
const directory = path43.join(
|
|
24958
|
+
path43.resolve(projectRoot),
|
|
24838
24959
|
".mancode",
|
|
24839
24960
|
"local",
|
|
24840
24961
|
"quarantine",
|
|
@@ -24850,7 +24971,7 @@ async function quarantineGitRefTaskBundle(projectRoot, remoteRevision, bundle) {
|
|
|
24850
24971
|
parsed.taskRef.taskId,
|
|
24851
24972
|
String(remoteRevision)
|
|
24852
24973
|
]);
|
|
24853
|
-
const target =
|
|
24974
|
+
const target = path43.join(directory, `${parsed.bundleDigest.slice(7)}.json`);
|
|
24854
24975
|
try {
|
|
24855
24976
|
await writeFile35(target, `${JSON.stringify(parsed, null, 2)}
|
|
24856
24977
|
`, {
|
|
@@ -24867,8 +24988,8 @@ async function readQuarantinedGitRefTaskBundle(projectRoot, remoteRevision, task
|
|
|
24867
24988
|
throw new Error("MANCODE_TRANSPORT_REVISION_INVALID");
|
|
24868
24989
|
}
|
|
24869
24990
|
const parsedTaskRef = parseTaskRefValue(taskRef);
|
|
24870
|
-
const directory =
|
|
24871
|
-
|
|
24991
|
+
const directory = path43.join(
|
|
24992
|
+
path43.resolve(projectRoot),
|
|
24872
24993
|
".mancode",
|
|
24873
24994
|
"local",
|
|
24874
24995
|
"quarantine",
|
|
@@ -24894,7 +25015,7 @@ async function readQuarantinedGitRefTaskBundle(projectRoot, remoteRevision, task
|
|
|
24894
25015
|
const matches = [];
|
|
24895
25016
|
for (const entry of entries.sort()) {
|
|
24896
25017
|
if (!/^[a-f0-9]{64}\.json$/.test(entry)) continue;
|
|
24897
|
-
const target =
|
|
25018
|
+
const target = path43.join(directory, entry);
|
|
24898
25019
|
const before = await lstat16(target);
|
|
24899
25020
|
if (!before.isFile() || before.isSymbolicLink()) {
|
|
24900
25021
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
@@ -24931,9 +25052,9 @@ function parseCodeRef(value) {
|
|
|
24931
25052
|
return { branch: value.branch, head: value.head };
|
|
24932
25053
|
}
|
|
24933
25054
|
async function ensureFixedDirectory(projectRoot, segments) {
|
|
24934
|
-
let current =
|
|
25055
|
+
let current = path43.resolve(projectRoot);
|
|
24935
25056
|
for (const segment of segments) {
|
|
24936
|
-
current =
|
|
25057
|
+
current = path43.join(current, segment);
|
|
24937
25058
|
try {
|
|
24938
25059
|
await mkdir27(current);
|
|
24939
25060
|
} catch (error) {
|
|
@@ -24946,9 +25067,9 @@ async function ensureFixedDirectory(projectRoot, segments) {
|
|
|
24946
25067
|
}
|
|
24947
25068
|
}
|
|
24948
25069
|
async function assertFixedDirectory(projectRoot, segments) {
|
|
24949
|
-
let current =
|
|
25070
|
+
let current = path43.resolve(projectRoot);
|
|
24950
25071
|
for (const segment of segments) {
|
|
24951
|
-
current =
|
|
25072
|
+
current = path43.join(current, segment);
|
|
24952
25073
|
const entry = await lstat16(current);
|
|
24953
25074
|
if (!entry.isDirectory() || entry.isSymbolicLink()) {
|
|
24954
25075
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
@@ -24964,7 +25085,7 @@ function isNotFound21(error) {
|
|
|
24964
25085
|
|
|
24965
25086
|
// src/team/git-ref-task-base.ts
|
|
24966
25087
|
import { lstat as lstat17, mkdir as mkdir28, readFile as readFile31, writeFile as writeFile36 } from "fs/promises";
|
|
24967
|
-
import
|
|
25088
|
+
import path44 from "path";
|
|
24968
25089
|
async function readGitRefTaskRemoteBase(projectRoot, taskRef) {
|
|
24969
25090
|
const parsedTaskRef = parseTaskRefValue(taskRef);
|
|
24970
25091
|
const runtime = await readProjectRuntimeContext(projectRoot);
|
|
@@ -25007,7 +25128,7 @@ async function recordGitRefTaskRemoteBase(projectRoot, remoteRevision, bundle) {
|
|
|
25007
25128
|
});
|
|
25008
25129
|
const directory = await ensureRemoteBaseDirectory(projectRoot);
|
|
25009
25130
|
const target = remoteBasePath(projectRoot, parsedBundle.taskRef);
|
|
25010
|
-
const temporary =
|
|
25131
|
+
const temporary = path44.join(
|
|
25011
25132
|
directory,
|
|
25012
25133
|
`.${parsedBundle.taskRef.taskId}.${process.pid}.${Date.now()}.tmp`
|
|
25013
25134
|
);
|
|
@@ -25044,7 +25165,7 @@ function parseGitRefTaskRemoteBase(value) {
|
|
|
25044
25165
|
};
|
|
25045
25166
|
}
|
|
25046
25167
|
async function ensureRemoteBaseDirectory(projectRoot) {
|
|
25047
|
-
let current =
|
|
25168
|
+
let current = path44.resolve(projectRoot);
|
|
25048
25169
|
for (const segment of [
|
|
25049
25170
|
".mancode",
|
|
25050
25171
|
"local",
|
|
@@ -25052,7 +25173,7 @@ async function ensureRemoteBaseDirectory(projectRoot) {
|
|
|
25052
25173
|
"git-ref",
|
|
25053
25174
|
"remote-bases"
|
|
25054
25175
|
]) {
|
|
25055
|
-
current =
|
|
25176
|
+
current = path44.join(current, segment);
|
|
25056
25177
|
try {
|
|
25057
25178
|
await mkdir28(current);
|
|
25058
25179
|
} catch (error) {
|
|
@@ -25066,7 +25187,7 @@ async function ensureRemoteBaseDirectory(projectRoot) {
|
|
|
25066
25187
|
return current;
|
|
25067
25188
|
}
|
|
25068
25189
|
async function assertRemoteBaseDirectory(projectRoot) {
|
|
25069
|
-
let current =
|
|
25190
|
+
let current = path44.resolve(projectRoot);
|
|
25070
25191
|
for (const segment of [
|
|
25071
25192
|
".mancode",
|
|
25072
25193
|
"local",
|
|
@@ -25074,7 +25195,7 @@ async function assertRemoteBaseDirectory(projectRoot) {
|
|
|
25074
25195
|
"git-ref",
|
|
25075
25196
|
"remote-bases"
|
|
25076
25197
|
]) {
|
|
25077
|
-
current =
|
|
25198
|
+
current = path44.join(current, segment);
|
|
25078
25199
|
const entry = await lstat17(current);
|
|
25079
25200
|
if (!entry.isDirectory() || entry.isSymbolicLink()) {
|
|
25080
25201
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
@@ -25083,8 +25204,8 @@ async function assertRemoteBaseDirectory(projectRoot) {
|
|
|
25083
25204
|
}
|
|
25084
25205
|
function remoteBasePath(projectRoot, taskRef) {
|
|
25085
25206
|
const parsed = parseTaskRefValue(taskRef);
|
|
25086
|
-
return
|
|
25087
|
-
|
|
25207
|
+
return path44.join(
|
|
25208
|
+
path44.resolve(projectRoot),
|
|
25088
25209
|
".mancode",
|
|
25089
25210
|
"local",
|
|
25090
25211
|
"cache",
|
|
@@ -25108,7 +25229,7 @@ function isNotFound22(error) {
|
|
|
25108
25229
|
|
|
25109
25230
|
// src/team/git-ref-materialization.ts
|
|
25110
25231
|
async function materializeGitRefTaskBundle(input) {
|
|
25111
|
-
const projectRoot =
|
|
25232
|
+
const projectRoot = path45.resolve(input.projectRoot);
|
|
25112
25233
|
const remoteRevision = positiveInteger3(
|
|
25113
25234
|
input.remoteRevision,
|
|
25114
25235
|
"git-ref materialization remoteRevision"
|
|
@@ -25435,7 +25556,7 @@ async function replaceVerifiedFile(taskRoot2, relativePath2, targetContent, pred
|
|
|
25435
25556
|
const target = safeTaskPath(taskRoot2, relativePath2);
|
|
25436
25557
|
await ensureSafeDirectory(
|
|
25437
25558
|
taskRoot2,
|
|
25438
|
-
|
|
25559
|
+
path45.dirname(relativePath2).split(path45.sep)
|
|
25439
25560
|
);
|
|
25440
25561
|
const current = await readSafeFileOrNull(target);
|
|
25441
25562
|
if (contentMatches(relativePath2, current, targetContent)) return;
|
|
@@ -25445,9 +25566,9 @@ async function replaceVerifiedFile(taskRoot2, relativePath2, targetContent, pred
|
|
|
25445
25566
|
if (current === null && (predecessorContent !== null || alternatePredecessorContent !== null) && relativePath2 !== "summary.md") {
|
|
25446
25567
|
throw new Error("MANCODE_SPLIT_BRAIN");
|
|
25447
25568
|
}
|
|
25448
|
-
const temporary =
|
|
25449
|
-
|
|
25450
|
-
`.${
|
|
25569
|
+
const temporary = path45.join(
|
|
25570
|
+
path45.dirname(target),
|
|
25571
|
+
`.${path45.basename(target)}.${process.pid}.${Date.now()}.tmp`
|
|
25451
25572
|
);
|
|
25452
25573
|
await writeFile37(temporary, targetContent, { encoding: "utf8", flag: "wx" });
|
|
25453
25574
|
await replaceFileAtomically(temporary, target);
|
|
@@ -25515,13 +25636,13 @@ async function readSafeFileOrNull(target) {
|
|
|
25515
25636
|
}
|
|
25516
25637
|
}
|
|
25517
25638
|
async function ensureSafeDirectory(root, segments) {
|
|
25518
|
-
let current =
|
|
25639
|
+
let current = path45.resolve(root);
|
|
25519
25640
|
for (const segment of segments) {
|
|
25520
25641
|
if (!segment || segment === ".") continue;
|
|
25521
25642
|
if (segment === ".." || segment.includes("/") || segment.includes("\\")) {
|
|
25522
25643
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
25523
25644
|
}
|
|
25524
|
-
current =
|
|
25645
|
+
current = path45.join(current, segment);
|
|
25525
25646
|
try {
|
|
25526
25647
|
await mkdir29(current);
|
|
25527
25648
|
} catch (error) {
|
|
@@ -25534,9 +25655,9 @@ async function ensureSafeDirectory(root, segments) {
|
|
|
25534
25655
|
}
|
|
25535
25656
|
}
|
|
25536
25657
|
function safeTaskPath(taskRoot2, relativePath2) {
|
|
25537
|
-
const target =
|
|
25538
|
-
const relative =
|
|
25539
|
-
if (!relative || relative.startsWith("..") ||
|
|
25658
|
+
const target = path45.resolve(taskRoot2, relativePath2);
|
|
25659
|
+
const relative = path45.relative(taskRoot2, target);
|
|
25660
|
+
if (!relative || relative.startsWith("..") || path45.isAbsolute(relative)) {
|
|
25540
25661
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
25541
25662
|
}
|
|
25542
25663
|
return target;
|
|
@@ -25559,8 +25680,8 @@ async function createJournal(projectRoot, journal) {
|
|
|
25559
25680
|
}
|
|
25560
25681
|
async function replaceJournal(projectRoot, journal) {
|
|
25561
25682
|
const target = journalPath(projectRoot, journal.operationId);
|
|
25562
|
-
const temporary =
|
|
25563
|
-
|
|
25683
|
+
const temporary = path45.join(
|
|
25684
|
+
path45.dirname(target),
|
|
25564
25685
|
`.${journal.operationId}.${process.pid}.${Date.now()}.tmp`
|
|
25565
25686
|
);
|
|
25566
25687
|
await writeFile37(temporary, serialize9(journal), {
|
|
@@ -25592,7 +25713,7 @@ async function listJournals(projectRoot) {
|
|
|
25592
25713
|
const journals = [];
|
|
25593
25714
|
for (const entry of entries.sort()) {
|
|
25594
25715
|
if (!entry.endsWith(".json")) continue;
|
|
25595
|
-
journals.push(await readJournal(
|
|
25716
|
+
journals.push(await readJournal(path45.join(directory, entry)));
|
|
25596
25717
|
}
|
|
25597
25718
|
return journals;
|
|
25598
25719
|
}
|
|
@@ -25658,8 +25779,8 @@ function result(status2, bundle, localJournalPath, taskHeadFence) {
|
|
|
25658
25779
|
};
|
|
25659
25780
|
}
|
|
25660
25781
|
function journalDirectory(projectRoot) {
|
|
25661
|
-
return
|
|
25662
|
-
|
|
25782
|
+
return path45.join(
|
|
25783
|
+
path45.resolve(projectRoot),
|
|
25663
25784
|
".mancode",
|
|
25664
25785
|
"local",
|
|
25665
25786
|
"journals",
|
|
@@ -25668,7 +25789,7 @@ function journalDirectory(projectRoot) {
|
|
|
25668
25789
|
}
|
|
25669
25790
|
function journalPath(projectRoot, operationId) {
|
|
25670
25791
|
assertUlid(operationId, "git-ref materialization operationId");
|
|
25671
|
-
return
|
|
25792
|
+
return path45.join(journalDirectory(projectRoot), `${operationId}.json`);
|
|
25672
25793
|
}
|
|
25673
25794
|
function serialize9(value) {
|
|
25674
25795
|
return `${JSON.stringify(value, null, 2)}
|
|
@@ -25704,7 +25825,7 @@ function isNotFound23(error) {
|
|
|
25704
25825
|
|
|
25705
25826
|
// src/team/git-ref-workflow-repair.ts
|
|
25706
25827
|
async function prepareGitRefWorkflowRepair(input) {
|
|
25707
|
-
const root =
|
|
25828
|
+
const root = path46.resolve(input.projectRoot);
|
|
25708
25829
|
const prepared2 = parsePrepared(input.prepared);
|
|
25709
25830
|
const pendingMetadata = parseWorkflowMetadata(input.pendingMetadata);
|
|
25710
25831
|
assertPendingMetadata2(prepared2, pendingMetadata);
|
|
@@ -25739,7 +25860,7 @@ async function prepareGitRefWorkflowRepair(input) {
|
|
|
25739
25860
|
}
|
|
25740
25861
|
async function recoverGitRefWorkflowRepair(projectRoot, operationId, transportReceipt = null, options = {}) {
|
|
25741
25862
|
assertUlid(operationId, "git-ref workflow repair operationId");
|
|
25742
|
-
const root =
|
|
25863
|
+
const root = path46.resolve(projectRoot);
|
|
25743
25864
|
let journal = await requireJournal(root, operationId);
|
|
25744
25865
|
await assertRecoveryAuthorized(root, journal, options);
|
|
25745
25866
|
if (journal.state === "committed" || journal.state === "aborted") {
|
|
@@ -26147,7 +26268,7 @@ function metadataFromBundle(bundle) {
|
|
|
26147
26268
|
return parseWorkflowMetadata(artifact2.content);
|
|
26148
26269
|
}
|
|
26149
26270
|
function metadataPath2(projectRoot, taskRef) {
|
|
26150
|
-
return
|
|
26271
|
+
return path46.join(taskRootPath(projectRoot, taskRef), "metadata.json");
|
|
26151
26272
|
}
|
|
26152
26273
|
async function readSafeFile(target) {
|
|
26153
26274
|
const before = await lstat19(target);
|
|
@@ -26162,17 +26283,17 @@ async function readSafeFile(target) {
|
|
|
26162
26283
|
return content;
|
|
26163
26284
|
}
|
|
26164
26285
|
async function atomicWrite(target, content) {
|
|
26165
|
-
const temporary =
|
|
26166
|
-
|
|
26167
|
-
`.${
|
|
26286
|
+
const temporary = path46.join(
|
|
26287
|
+
path46.dirname(target),
|
|
26288
|
+
`.${path46.basename(target)}.${process.pid}.${Date.now()}.tmp`
|
|
26168
26289
|
);
|
|
26169
26290
|
await writeFile38(temporary, content, { encoding: "utf8", flag: "wx" });
|
|
26170
26291
|
await replaceFileAtomically(temporary, target);
|
|
26171
26292
|
}
|
|
26172
26293
|
async function ensureJournalDirectory(projectRoot) {
|
|
26173
|
-
let current =
|
|
26294
|
+
let current = path46.resolve(projectRoot);
|
|
26174
26295
|
for (const segment of [".mancode", "local", "journals", "git-ref-workflow"]) {
|
|
26175
|
-
current =
|
|
26296
|
+
current = path46.join(current, segment);
|
|
26176
26297
|
try {
|
|
26177
26298
|
await mkdir30(current);
|
|
26178
26299
|
} catch (error) {
|
|
@@ -27017,7 +27138,7 @@ function parseExpectedRevision2(value) {
|
|
|
27017
27138
|
|
|
27018
27139
|
// src/commands/design.ts
|
|
27019
27140
|
import { readFile as readFile35, stat as stat4 } from "fs/promises";
|
|
27020
|
-
import
|
|
27141
|
+
import path48 from "path";
|
|
27021
27142
|
import process2 from "process";
|
|
27022
27143
|
|
|
27023
27144
|
// src/context/design-policy.ts
|
|
@@ -27029,7 +27150,7 @@ import {
|
|
|
27029
27150
|
rm as rm18,
|
|
27030
27151
|
writeFile as writeFile39
|
|
27031
27152
|
} from "fs/promises";
|
|
27032
|
-
import
|
|
27153
|
+
import path47 from "path";
|
|
27033
27154
|
var DEFAULT_DESIGN_POLICY = {
|
|
27034
27155
|
schemaVersion: 1,
|
|
27035
27156
|
revision: 0,
|
|
@@ -27043,8 +27164,8 @@ var DEFAULT_DESIGN_POLICY = {
|
|
|
27043
27164
|
updatedAt: "1970-01-01T00:00:00.000Z"
|
|
27044
27165
|
};
|
|
27045
27166
|
function designPolicyPath(projectRoot) {
|
|
27046
|
-
return
|
|
27047
|
-
|
|
27167
|
+
return path47.join(
|
|
27168
|
+
path47.resolve(projectRoot),
|
|
27048
27169
|
".mancode",
|
|
27049
27170
|
"shared",
|
|
27050
27171
|
"context",
|
|
@@ -27132,7 +27253,7 @@ async function configureDesignPolicy(input) {
|
|
|
27132
27253
|
const operationId = input.operationId ?? createUlid();
|
|
27133
27254
|
assertUlid(operationId, "design policy operationId");
|
|
27134
27255
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
27135
|
-
const root =
|
|
27256
|
+
const root = path47.resolve(input.projectRoot);
|
|
27136
27257
|
const runtime = await readProjectRuntimeContext(root);
|
|
27137
27258
|
const store = resolveCoordinationEntityHomeStore(
|
|
27138
27259
|
runtime.entityHomeStoreContext
|
|
@@ -27188,10 +27309,10 @@ function isDesignBrowserValidation(value) {
|
|
|
27188
27309
|
}
|
|
27189
27310
|
async function writeDesignPolicy(projectRoot, policy) {
|
|
27190
27311
|
const target = designPolicyPath(projectRoot);
|
|
27191
|
-
await mkdir31(
|
|
27192
|
-
const temporary =
|
|
27193
|
-
|
|
27194
|
-
`.${
|
|
27312
|
+
await mkdir31(path47.dirname(target), { recursive: true });
|
|
27313
|
+
const temporary = path47.join(
|
|
27314
|
+
path47.dirname(target),
|
|
27315
|
+
`.${path47.basename(target)}.${process.pid}.${Date.now()}.tmp`
|
|
27195
27316
|
);
|
|
27196
27317
|
await writeFile39(temporary, `${JSON.stringify(policy, null, 2)}
|
|
27197
27318
|
`, {
|
|
@@ -27205,13 +27326,13 @@ async function writeDesignPolicy(projectRoot, policy) {
|
|
|
27205
27326
|
}
|
|
27206
27327
|
}
|
|
27207
27328
|
async function assertDesignPolicyPathSafe(projectRoot) {
|
|
27208
|
-
const root =
|
|
27329
|
+
const root = path47.resolve(projectRoot);
|
|
27209
27330
|
const policyPath = designPolicyPath(root);
|
|
27210
|
-
const contextDir =
|
|
27331
|
+
const contextDir = path47.dirname(policyPath);
|
|
27211
27332
|
try {
|
|
27212
27333
|
for (const directory of [
|
|
27213
|
-
|
|
27214
|
-
|
|
27334
|
+
path47.join(root, ".mancode"),
|
|
27335
|
+
path47.join(root, ".mancode", "shared"),
|
|
27215
27336
|
contextDir
|
|
27216
27337
|
]) {
|
|
27217
27338
|
const info = await lstat20(directory);
|
|
@@ -27223,8 +27344,8 @@ async function assertDesignPolicyPathSafe(projectRoot) {
|
|
|
27223
27344
|
realpath2(root),
|
|
27224
27345
|
realpath2(contextDir)
|
|
27225
27346
|
]);
|
|
27226
|
-
const relative =
|
|
27227
|
-
if (
|
|
27347
|
+
const relative = path47.relative(resolvedRoot, resolvedContextDir);
|
|
27348
|
+
if (path47.isAbsolute(relative) || relative === ".." || relative.startsWith(`..${path47.sep}`)) {
|
|
27228
27349
|
throw new Error("MANCODE_DESIGN_POLICY_PATH_UNSAFE");
|
|
27229
27350
|
}
|
|
27230
27351
|
try {
|
|
@@ -27479,7 +27600,7 @@ async function readProfile(rootDir, kind) {
|
|
|
27479
27600
|
try {
|
|
27480
27601
|
return JSON.parse(
|
|
27481
27602
|
await readFile35(
|
|
27482
|
-
|
|
27603
|
+
path48.join(rootDir, ".mancode", "project-profile.json"),
|
|
27483
27604
|
"utf8"
|
|
27484
27605
|
)
|
|
27485
27606
|
);
|
|
@@ -27488,7 +27609,7 @@ async function readProfile(rootDir, kind) {
|
|
|
27488
27609
|
}
|
|
27489
27610
|
}
|
|
27490
27611
|
async function readStyleSummary(rootDir, kind) {
|
|
27491
|
-
const cachePath = kind === "continuity" ?
|
|
27612
|
+
const cachePath = kind === "continuity" ? path48.join(rootDir, ".mancode", "local", "cache", "style-tokens.json") : path48.join(rootDir, ".mancode", "aesthetics", "style-tokens.json");
|
|
27492
27613
|
try {
|
|
27493
27614
|
const raw = JSON.parse(await readFile35(cachePath, "utf8"));
|
|
27494
27615
|
return sanitizeStyleSummary(rootDir, raw);
|
|
@@ -27529,7 +27650,7 @@ async function styleFreshness(rootDir, scopeRoot, lastScanned, sourceFiles) {
|
|
|
27529
27650
|
const scannedAt = Date.parse(lastScanned);
|
|
27530
27651
|
for (const file of sourceFiles) {
|
|
27531
27652
|
try {
|
|
27532
|
-
const info = await stat4(
|
|
27653
|
+
const info = await stat4(path48.resolve(rootDir, scopeRoot, file));
|
|
27533
27654
|
if (info.mtimeMs > scannedAt) return "stale";
|
|
27534
27655
|
} catch {
|
|
27535
27656
|
return "stale";
|
|
@@ -27606,10 +27727,10 @@ function emptyStyleSummary() {
|
|
|
27606
27727
|
};
|
|
27607
27728
|
}
|
|
27608
27729
|
async function initializedKind(rootDir) {
|
|
27609
|
-
if (await exists(
|
|
27730
|
+
if (await exists(path48.join(rootDir, ".mancode", "schema.json"))) {
|
|
27610
27731
|
return "continuity";
|
|
27611
27732
|
}
|
|
27612
|
-
if (await exists(
|
|
27733
|
+
if (await exists(path48.join(rootDir, ".mancode", "state.json")))
|
|
27613
27734
|
return "legacy";
|
|
27614
27735
|
return null;
|
|
27615
27736
|
}
|
|
@@ -27674,7 +27795,7 @@ function safeShortText(value) {
|
|
|
27674
27795
|
return typeof value === "string" && value.length <= 100 && /^[A-Za-z0-9@/_. -]+$/.test(value) ? value : null;
|
|
27675
27796
|
}
|
|
27676
27797
|
function isSafeRelativeFile(value) {
|
|
27677
|
-
return value.length <= 240 && !
|
|
27798
|
+
return value.length <= 240 && !path48.isAbsolute(value) && !value.includes("\0") && value.split(/[\\/]/).every((part) => part !== "" && part !== "." && part !== "..");
|
|
27678
27799
|
}
|
|
27679
27800
|
function parseNonNegativeInteger2(value) {
|
|
27680
27801
|
if (value === void 0 || !/^\d+$/.test(value)) return null;
|
|
@@ -27682,7 +27803,7 @@ function parseNonNegativeInteger2(value) {
|
|
|
27682
27803
|
return Number.isSafeInteger(parsed) ? parsed : null;
|
|
27683
27804
|
}
|
|
27684
27805
|
function relativePath(rootDir, target) {
|
|
27685
|
-
return
|
|
27806
|
+
return path48.relative(path48.resolve(rootDir), target).split(path48.sep).join("/");
|
|
27686
27807
|
}
|
|
27687
27808
|
function isRecord6(value) {
|
|
27688
27809
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -27715,12 +27836,12 @@ function errorCode3(error, fallback) {
|
|
|
27715
27836
|
import { randomUUID } from "crypto";
|
|
27716
27837
|
import { promises as fs4 } from "fs";
|
|
27717
27838
|
import os from "os";
|
|
27718
|
-
import
|
|
27839
|
+
import path54 from "path";
|
|
27719
27840
|
import process6 from "process";
|
|
27720
27841
|
|
|
27721
27842
|
// src/installers/platform-status.ts
|
|
27722
27843
|
import { promises as fs } from "fs";
|
|
27723
|
-
import
|
|
27844
|
+
import path49 from "path";
|
|
27724
27845
|
async function checkPlatformStatus(rootDir, platform, installed) {
|
|
27725
27846
|
const readiness = await checkPlatformReadiness(rootDir, platform);
|
|
27726
27847
|
return {
|
|
@@ -27737,13 +27858,13 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
27737
27858
|
if (platform === "claude-code") {
|
|
27738
27859
|
const [hasSoloSkill, registered, hasHookFiles] = await Promise.all([
|
|
27739
27860
|
fileMatches(
|
|
27740
|
-
|
|
27861
|
+
path49.join(rootDir, ".claude", "skills", "solo", "SKILL.md"),
|
|
27741
27862
|
(content) => isGeneratedClaudeSkill(content, "solo")
|
|
27742
27863
|
),
|
|
27743
27864
|
claudeHooksRegistered(rootDir),
|
|
27744
27865
|
pathsExist([
|
|
27745
|
-
|
|
27746
|
-
|
|
27866
|
+
path49.join(rootDir, ".mancode", "hooks", "session-start.mjs"),
|
|
27867
|
+
path49.join(rootDir, ".mancode", "hooks", "user-prompt-submit.mjs")
|
|
27747
27868
|
])
|
|
27748
27869
|
]);
|
|
27749
27870
|
const present = hasSoloSkill && registered && hasHookFiles;
|
|
@@ -27759,7 +27880,7 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
27759
27880
|
if (platform === "cursor") {
|
|
27760
27881
|
const hasCoreRules = await allManagedSkills(
|
|
27761
27882
|
MANCODE_CURSOR_CORE_RULE_FILES.map(
|
|
27762
|
-
(file) =>
|
|
27883
|
+
(file) => path49.join(rootDir, ".cursor", "rules", file)
|
|
27763
27884
|
),
|
|
27764
27885
|
[CURSOR_RULE_MANAGED_MARKER]
|
|
27765
27886
|
);
|
|
@@ -27774,13 +27895,13 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
27774
27895
|
const [hasRules, hasCommands] = await Promise.all([
|
|
27775
27896
|
allManagedSkills(
|
|
27776
27897
|
MANCODE_CURSOR_RULE_FILES.map(
|
|
27777
|
-
(file) =>
|
|
27898
|
+
(file) => path49.join(rootDir, ".cursor", "rules", file)
|
|
27778
27899
|
),
|
|
27779
27900
|
[CURSOR_RULE_MANAGED_MARKER]
|
|
27780
27901
|
),
|
|
27781
27902
|
allManagedSkills(
|
|
27782
27903
|
MODE_NAMES.map(
|
|
27783
|
-
(mode) =>
|
|
27904
|
+
(mode) => path49.join(rootDir, ".cursor", "commands", `${mode}.md`)
|
|
27784
27905
|
),
|
|
27785
27906
|
[MODE_FILE_MANAGED_MARKER]
|
|
27786
27907
|
)
|
|
@@ -27793,7 +27914,7 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
27793
27914
|
};
|
|
27794
27915
|
}
|
|
27795
27916
|
if (platform === "codex") {
|
|
27796
|
-
const hasBlock2 = await fileHasManagedBlock(
|
|
27917
|
+
const hasBlock2 = await fileHasManagedBlock(path49.join(rootDir, "AGENTS.md"));
|
|
27797
27918
|
if (!hasBlock2) {
|
|
27798
27919
|
return {
|
|
27799
27920
|
present: false,
|
|
@@ -27810,9 +27931,9 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
27810
27931
|
readyDetail: "managed block present"
|
|
27811
27932
|
};
|
|
27812
27933
|
}
|
|
27813
|
-
const skillsDir =
|
|
27934
|
+
const skillsDir = path49.join(rootDir, ".agents", "skills");
|
|
27814
27935
|
const hasSkills = await allManagedSkills(
|
|
27815
|
-
MODE_NAMES.map((mode) =>
|
|
27936
|
+
MODE_NAMES.map((mode) => path49.join(skillsDir, mode, "SKILL.md")),
|
|
27816
27937
|
MANCODE_AGENT_SKILL_MARKERS
|
|
27817
27938
|
);
|
|
27818
27939
|
return {
|
|
@@ -27824,7 +27945,7 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
27824
27945
|
}
|
|
27825
27946
|
if (platform === "zcode") {
|
|
27826
27947
|
const hasBlock2 = await fileHasManagedBlock(
|
|
27827
|
-
|
|
27948
|
+
path49.join(rootDir, "AGENTS.md"),
|
|
27828
27949
|
ZCODE_MANCODE_START_MARKER,
|
|
27829
27950
|
ZCODE_MANCODE_END_MARKER
|
|
27830
27951
|
);
|
|
@@ -27844,9 +27965,9 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
27844
27965
|
readyDetail: "managed block present"
|
|
27845
27966
|
};
|
|
27846
27967
|
}
|
|
27847
|
-
const skillsDir =
|
|
27968
|
+
const skillsDir = path49.join(rootDir, ".agents", "skills");
|
|
27848
27969
|
const hasSkills = await allManagedSkills(
|
|
27849
|
-
MODE_NAMES.map((mode) =>
|
|
27970
|
+
MODE_NAMES.map((mode) => path49.join(skillsDir, mode, "SKILL.md")),
|
|
27850
27971
|
MANCODE_AGENT_SKILL_MARKERS
|
|
27851
27972
|
);
|
|
27852
27973
|
return {
|
|
@@ -27858,7 +27979,7 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
27858
27979
|
}
|
|
27859
27980
|
if (platform === "kimi-code") {
|
|
27860
27981
|
const hasBlock2 = await fileHasManagedBlock(
|
|
27861
|
-
|
|
27982
|
+
path49.join(rootDir, "AGENTS.md"),
|
|
27862
27983
|
KIMI_MANCODE_START_MARKER,
|
|
27863
27984
|
KIMI_MANCODE_END_MARKER
|
|
27864
27985
|
);
|
|
@@ -27878,9 +27999,9 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
27878
27999
|
readyDetail: "managed block present"
|
|
27879
28000
|
};
|
|
27880
28001
|
}
|
|
27881
|
-
const skillsDir =
|
|
28002
|
+
const skillsDir = path49.join(rootDir, ".agents", "skills");
|
|
27882
28003
|
const hasSkills = await allManagedSkills(
|
|
27883
|
-
MODE_NAMES.map((mode) =>
|
|
28004
|
+
MODE_NAMES.map((mode) => path49.join(skillsDir, mode, "SKILL.md")),
|
|
27884
28005
|
MANCODE_AGENT_SKILL_MARKERS
|
|
27885
28006
|
);
|
|
27886
28007
|
return {
|
|
@@ -27892,7 +28013,7 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
27892
28013
|
}
|
|
27893
28014
|
if (platform === "qoder") {
|
|
27894
28015
|
const hasBlock2 = await fileHasManagedBlock(
|
|
27895
|
-
|
|
28016
|
+
path49.join(rootDir, "AGENTS.md"),
|
|
27896
28017
|
QODER_MANCODE_START_MARKER,
|
|
27897
28018
|
QODER_MANCODE_END_MARKER
|
|
27898
28019
|
);
|
|
@@ -27912,9 +28033,9 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
27912
28033
|
readyDetail: "managed block present"
|
|
27913
28034
|
};
|
|
27914
28035
|
}
|
|
27915
|
-
const commandsDir =
|
|
28036
|
+
const commandsDir = path49.join(rootDir, ".qoder", "commands");
|
|
27916
28037
|
const hasCommands = await allManagedSkills(
|
|
27917
|
-
MODE_NAMES.map((mode) =>
|
|
28038
|
+
MODE_NAMES.map((mode) => path49.join(commandsDir, `${mode}.md`)),
|
|
27918
28039
|
[MODE_FILE_MANAGED_MARKER]
|
|
27919
28040
|
);
|
|
27920
28041
|
return {
|
|
@@ -27926,7 +28047,7 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
27926
28047
|
}
|
|
27927
28048
|
if (platform === "dsh") {
|
|
27928
28049
|
const hasBlock2 = await fileHasManagedBlock(
|
|
27929
|
-
|
|
28050
|
+
path49.join(rootDir, "AGENTS.md"),
|
|
27930
28051
|
DSH_MANCODE_START_MARKER,
|
|
27931
28052
|
DSH_MANCODE_END_MARKER
|
|
27932
28053
|
);
|
|
@@ -27946,9 +28067,9 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
27946
28067
|
readyDetail: "managed block present"
|
|
27947
28068
|
};
|
|
27948
28069
|
}
|
|
27949
|
-
const skillsDir =
|
|
28070
|
+
const skillsDir = path49.join(rootDir, ".dsh", "skills");
|
|
27950
28071
|
const hasSkills = await allManagedSkills(
|
|
27951
|
-
MODE_NAMES.map((mode) =>
|
|
28072
|
+
MODE_NAMES.map((mode) => path49.join(skillsDir, mode, "SKILL.md")),
|
|
27952
28073
|
MANCODE_DSH_SKILL_MARKERS
|
|
27953
28074
|
);
|
|
27954
28075
|
return {
|
|
@@ -27959,7 +28080,7 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
27959
28080
|
};
|
|
27960
28081
|
}
|
|
27961
28082
|
const hasBlock = await fileHasManagedBlock(
|
|
27962
|
-
|
|
28083
|
+
path49.join(rootDir, ".github", "copilot-instructions.md")
|
|
27963
28084
|
);
|
|
27964
28085
|
if (!hasBlock) {
|
|
27965
28086
|
return {
|
|
@@ -27970,9 +28091,9 @@ async function checkPlatformReadiness(rootDir, platform) {
|
|
|
27970
28091
|
};
|
|
27971
28092
|
}
|
|
27972
28093
|
if (!await isPlatformMinimal(rootDir, "copilot")) {
|
|
27973
|
-
const promptsDir =
|
|
28094
|
+
const promptsDir = path49.join(rootDir, ".github", "prompts");
|
|
27974
28095
|
const hasPrompts = await allManagedSkills(
|
|
27975
|
-
MODE_NAMES.map((mode) =>
|
|
28096
|
+
MODE_NAMES.map((mode) => path49.join(promptsDir, `${mode}.prompt.md`)),
|
|
27976
28097
|
[MODE_FILE_MANAGED_MARKER]
|
|
27977
28098
|
);
|
|
27978
28099
|
return {
|
|
@@ -28005,13 +28126,13 @@ async function allManagedSkills(paths, markers) {
|
|
|
28005
28126
|
async function claudeFullContentReady(rootDir) {
|
|
28006
28127
|
const skillChecks = MVP2_SKILLS.map(
|
|
28007
28128
|
(skill) => fileMatches(
|
|
28008
|
-
|
|
28129
|
+
path49.join(rootDir, ".claude", "skills", skill.name, "SKILL.md"),
|
|
28009
28130
|
(content) => isGeneratedClaudeSkill(content, skill.name)
|
|
28010
28131
|
)
|
|
28011
28132
|
);
|
|
28012
28133
|
const agentChecks = ALL_AGENTS.map(
|
|
28013
28134
|
(agent) => fileMatches(
|
|
28014
|
-
|
|
28135
|
+
path49.join(rootDir, ".claude", "agents", `${agent.name}.md`),
|
|
28015
28136
|
(content) => isGeneratedClaudeAgent(content, agent.name)
|
|
28016
28137
|
)
|
|
28017
28138
|
);
|
|
@@ -28039,7 +28160,7 @@ async function fileHasAnyMarker(filePath, needles) {
|
|
|
28039
28160
|
async function isPlatformMinimal(rootDir, platform) {
|
|
28040
28161
|
try {
|
|
28041
28162
|
const raw = await fs.readFile(
|
|
28042
|
-
|
|
28163
|
+
path49.join(rootDir, ".mancode", "config.json"),
|
|
28043
28164
|
"utf-8"
|
|
28044
28165
|
);
|
|
28045
28166
|
const config = JSON.parse(raw);
|
|
@@ -28061,7 +28182,7 @@ async function fileHasManagedBlock(filePath, startMarker = DEFAULT_MANCODE_START
|
|
|
28061
28182
|
async function claudeHooksRegistered(rootDir) {
|
|
28062
28183
|
try {
|
|
28063
28184
|
const raw = await fs.readFile(
|
|
28064
|
-
|
|
28185
|
+
path49.join(rootDir, ".claude", "settings.json"),
|
|
28065
28186
|
"utf-8"
|
|
28066
28187
|
);
|
|
28067
28188
|
const settings = JSON.parse(raw);
|
|
@@ -28104,7 +28225,7 @@ function isRecord7(value) {
|
|
|
28104
28225
|
// src/system/detect-team.ts
|
|
28105
28226
|
import { execFile as execFile5 } from "child_process";
|
|
28106
28227
|
import { access as access2 } from "fs/promises";
|
|
28107
|
-
import
|
|
28228
|
+
import path50 from "path";
|
|
28108
28229
|
import process3 from "process";
|
|
28109
28230
|
import { promisify as promisify5 } from "util";
|
|
28110
28231
|
var execFileAsync = promisify5(execFile5);
|
|
@@ -28214,7 +28335,7 @@ async function anyPathExists(projectRoot, candidates) {
|
|
|
28214
28335
|
const results = await Promise.all(
|
|
28215
28336
|
candidates.map(async (candidate) => {
|
|
28216
28337
|
try {
|
|
28217
|
-
await access2(
|
|
28338
|
+
await access2(path50.join(projectRoot, candidate));
|
|
28218
28339
|
return true;
|
|
28219
28340
|
} catch {
|
|
28220
28341
|
return false;
|
|
@@ -28255,7 +28376,7 @@ async function detectSystemDeps(env = process4.env) {
|
|
|
28255
28376
|
// src/system/init-onboarding.ts
|
|
28256
28377
|
import { execFileSync } from "child_process";
|
|
28257
28378
|
import { promises as fs2 } from "fs";
|
|
28258
|
-
import
|
|
28379
|
+
import path51 from "path";
|
|
28259
28380
|
import process5 from "process";
|
|
28260
28381
|
import { stdin, stdout } from "process";
|
|
28261
28382
|
import { createInterface } from "readline/promises";
|
|
@@ -28361,7 +28482,7 @@ async function detectPlatformHints(rootDir, environment = process5.env) {
|
|
|
28361
28482
|
if (environment.DSH_SHELL === "1") hints.add("dsh");
|
|
28362
28483
|
const exists2 = async (relative) => {
|
|
28363
28484
|
try {
|
|
28364
|
-
await fs2.access(
|
|
28485
|
+
await fs2.access(path51.join(rootDir, relative));
|
|
28365
28486
|
return true;
|
|
28366
28487
|
} catch {
|
|
28367
28488
|
return false;
|
|
@@ -28511,7 +28632,7 @@ function createTerminalPrompter() {
|
|
|
28511
28632
|
|
|
28512
28633
|
// src/system/scan-aesthetics.ts
|
|
28513
28634
|
import { promises as fs3 } from "fs";
|
|
28514
|
-
import
|
|
28635
|
+
import path52 from "path";
|
|
28515
28636
|
var MAX_COMPONENT_SCAN_DEPTH = 12;
|
|
28516
28637
|
var MAX_COMPONENT_FILES = 2e3;
|
|
28517
28638
|
async function scanAesthetics(projectRoot, uiLibrary = null, scopeRoot = ".") {
|
|
@@ -28547,7 +28668,7 @@ async function scanAesthetics(projectRoot, uiLibrary = null, scopeRoot = ".") {
|
|
|
28547
28668
|
} else if (await hasTailwindDep(projectRoot) || uiLibrary) {
|
|
28548
28669
|
matchLevel = "low";
|
|
28549
28670
|
}
|
|
28550
|
-
if (uiLibrary && await pathExists5(
|
|
28671
|
+
if (uiLibrary && await pathExists5(path52.join(projectRoot, "package.json"))) {
|
|
28551
28672
|
sourceFiles.push("package.json");
|
|
28552
28673
|
}
|
|
28553
28674
|
sourceFiles.push(...cssScan.sourceFiles);
|
|
@@ -28573,7 +28694,7 @@ async function findTailwindConfig(projectRoot) {
|
|
|
28573
28694
|
"tailwind.config.mjs"
|
|
28574
28695
|
];
|
|
28575
28696
|
for (const name of candidates) {
|
|
28576
|
-
const absPath =
|
|
28697
|
+
const absPath = path52.join(projectRoot, name);
|
|
28577
28698
|
if (await pathExists5(absPath)) {
|
|
28578
28699
|
return { absPath, relPath: name };
|
|
28579
28700
|
}
|
|
@@ -28800,7 +28921,7 @@ async function scanComponents(projectRoot) {
|
|
|
28800
28921
|
const names = /* @__PURE__ */ new Set();
|
|
28801
28922
|
let visitedFiles = 0;
|
|
28802
28923
|
for (const relRoot of roots) {
|
|
28803
|
-
const absRoot =
|
|
28924
|
+
const absRoot = path52.join(projectRoot, relRoot);
|
|
28804
28925
|
if (!await pathExists5(absRoot)) continue;
|
|
28805
28926
|
visitedFiles = await collectComponentNames(absRoot, names, 0, visitedFiles);
|
|
28806
28927
|
if (visitedFiles >= MAX_COMPONENT_FILES) break;
|
|
@@ -28820,7 +28941,7 @@ async function collectComponentNames(dir, names, depth, visitedFiles) {
|
|
|
28820
28941
|
}
|
|
28821
28942
|
for (const entry of entries) {
|
|
28822
28943
|
if (fileCount >= MAX_COMPONENT_FILES) return fileCount;
|
|
28823
|
-
const abs =
|
|
28944
|
+
const abs = path52.join(dir, entry);
|
|
28824
28945
|
let info;
|
|
28825
28946
|
try {
|
|
28826
28947
|
info = await fs3.lstat(abs);
|
|
@@ -28841,7 +28962,7 @@ async function collectComponentNames(dir, names, depth, visitedFiles) {
|
|
|
28841
28962
|
""
|
|
28842
28963
|
);
|
|
28843
28964
|
if (base === "index") {
|
|
28844
|
-
base =
|
|
28965
|
+
base = path52.basename(dir);
|
|
28845
28966
|
}
|
|
28846
28967
|
if (base.startsWith(".")) continue;
|
|
28847
28968
|
const componentName = toPascalCase(base);
|
|
@@ -28863,7 +28984,7 @@ async function scanCssVariables(projectRoot) {
|
|
|
28863
28984
|
const variables = {};
|
|
28864
28985
|
const sourceFiles = [];
|
|
28865
28986
|
for (const relPath of candidates) {
|
|
28866
|
-
const absPath =
|
|
28987
|
+
const absPath = path52.join(projectRoot, relPath);
|
|
28867
28988
|
if (!await pathExists5(absPath)) continue;
|
|
28868
28989
|
const content = await fs3.readFile(absPath, "utf-8");
|
|
28869
28990
|
const found = extractCssVariables(content);
|
|
@@ -28909,7 +29030,7 @@ function toPascalCase(value) {
|
|
|
28909
29030
|
async function hasTailwindDep(projectRoot) {
|
|
28910
29031
|
try {
|
|
28911
29032
|
const raw = await fs3.readFile(
|
|
28912
|
-
|
|
29033
|
+
path52.join(projectRoot, "package.json"),
|
|
28913
29034
|
"utf-8"
|
|
28914
29035
|
);
|
|
28915
29036
|
const pkg = JSON.parse(raw);
|
|
@@ -28941,8 +29062,8 @@ import {
|
|
|
28941
29062
|
rm as rm19,
|
|
28942
29063
|
writeFile as writeFile40
|
|
28943
29064
|
} from "fs/promises";
|
|
28944
|
-
import
|
|
28945
|
-
var JOURNAL_RELATIVE_DIRECTORY =
|
|
29065
|
+
import path53 from "path";
|
|
29066
|
+
var JOURNAL_RELATIVE_DIRECTORY = path53.join(
|
|
28946
29067
|
"local",
|
|
28947
29068
|
"runtime",
|
|
28948
29069
|
"initialization"
|
|
@@ -28997,7 +29118,7 @@ async function stageGreenfieldInitialization(input) {
|
|
|
28997
29118
|
operationId: normalized.operationId,
|
|
28998
29119
|
workspaceId: normalized.workspaceId,
|
|
28999
29120
|
state: "staged",
|
|
29000
|
-
stagingDirectoryName:
|
|
29121
|
+
stagingDirectoryName: path53.basename(stagingRoot),
|
|
29001
29122
|
targetDirectoryName: ".mancode",
|
|
29002
29123
|
manifestDigest: digestCanonicalJson(manifest),
|
|
29003
29124
|
configDigest: digestCanonicalJson(config),
|
|
@@ -29030,7 +29151,7 @@ async function stageGreenfieldInitialization(input) {
|
|
|
29030
29151
|
return journal;
|
|
29031
29152
|
}
|
|
29032
29153
|
async function publishGreenfieldInitialization(input) {
|
|
29033
|
-
const root =
|
|
29154
|
+
const root = path53.resolve(input.projectRoot);
|
|
29034
29155
|
assertUlid(input.operationId, "greenfield operationId");
|
|
29035
29156
|
const stagingRoot = greenfieldStagingPath(root, input.operationId);
|
|
29036
29157
|
const targetRoot = greenfieldTargetPath(root);
|
|
@@ -29065,10 +29186,10 @@ async function initializeGreenfield(input, publication) {
|
|
|
29065
29186
|
}
|
|
29066
29187
|
function greenfieldStagingPath(projectRoot, operationId) {
|
|
29067
29188
|
assertUlid(operationId, "greenfield operationId");
|
|
29068
|
-
return
|
|
29189
|
+
return path53.join(path53.resolve(projectRoot), `.mancode.init-${operationId}`);
|
|
29069
29190
|
}
|
|
29070
29191
|
function greenfieldTargetPath(projectRoot) {
|
|
29071
|
-
return
|
|
29192
|
+
return path53.join(path53.resolve(projectRoot), ".mancode");
|
|
29072
29193
|
}
|
|
29073
29194
|
function parseGreenfieldInitializationJournal(value) {
|
|
29074
29195
|
assertRecord(value, "greenfield initialization journal");
|
|
@@ -29211,7 +29332,7 @@ async function finishPublishedInitialization(input, stagedJournal) {
|
|
|
29211
29332
|
activatedAt: (input.now ?? /* @__PURE__ */ new Date()).toISOString()
|
|
29212
29333
|
};
|
|
29213
29334
|
assertSchemaManifestTransition(manifest, activeManifest);
|
|
29214
|
-
await writeJson(
|
|
29335
|
+
await writeJson(path53.join(targetRoot, "schema.json"), activeManifest);
|
|
29215
29336
|
throwIfOperationCrashInjected(
|
|
29216
29337
|
"greenfield_initialize",
|
|
29217
29338
|
"activate-v3-manifest"
|
|
@@ -29227,55 +29348,55 @@ async function finishPublishedInitialization(input, stagedJournal) {
|
|
|
29227
29348
|
}
|
|
29228
29349
|
async function writeGreenfieldLayout(stagingRoot, manifest, config, policy, projectFacts, journal, privacy) {
|
|
29229
29350
|
await Promise.all([
|
|
29230
|
-
mkdir32(
|
|
29231
|
-
mkdir32(
|
|
29351
|
+
mkdir32(path53.join(stagingRoot, "shared", "context"), { recursive: true }),
|
|
29352
|
+
mkdir32(path53.join(stagingRoot, "shared", "memory", "decisions"), {
|
|
29232
29353
|
recursive: true
|
|
29233
29354
|
}),
|
|
29234
|
-
mkdir32(
|
|
29355
|
+
mkdir32(path53.join(stagingRoot, "shared", "team", "actors"), {
|
|
29235
29356
|
recursive: true
|
|
29236
29357
|
}),
|
|
29237
|
-
mkdir32(
|
|
29358
|
+
mkdir32(path53.join(stagingRoot, "shared", "team", "handoffs"), {
|
|
29238
29359
|
recursive: true
|
|
29239
29360
|
}),
|
|
29240
|
-
mkdir32(
|
|
29361
|
+
mkdir32(path53.join(stagingRoot, "shared", "team", "events"), {
|
|
29241
29362
|
recursive: true
|
|
29242
29363
|
}),
|
|
29243
|
-
mkdir32(
|
|
29364
|
+
mkdir32(path53.join(stagingRoot, "shared", "team", "transport"), {
|
|
29244
29365
|
recursive: true
|
|
29245
29366
|
}),
|
|
29246
|
-
mkdir32(
|
|
29247
|
-
mkdir32(
|
|
29367
|
+
mkdir32(path53.join(stagingRoot, "local", "sessions"), { recursive: true }),
|
|
29368
|
+
mkdir32(path53.join(stagingRoot, JOURNAL_RELATIVE_DIRECTORY), {
|
|
29248
29369
|
recursive: true
|
|
29249
29370
|
}),
|
|
29250
|
-
mkdir32(
|
|
29251
|
-
mkdir32(
|
|
29252
|
-
mkdir32(
|
|
29253
|
-
mkdir32(
|
|
29254
|
-
mkdir32(
|
|
29371
|
+
mkdir32(path53.join(stagingRoot, "local", "workflows"), { recursive: true }),
|
|
29372
|
+
mkdir32(path53.join(stagingRoot, "local", "quarantine"), { recursive: true }),
|
|
29373
|
+
mkdir32(path53.join(stagingRoot, "local", "publish"), { recursive: true }),
|
|
29374
|
+
mkdir32(path53.join(stagingRoot, "local", "cache"), { recursive: true }),
|
|
29375
|
+
mkdir32(path53.join(stagingRoot, "runtime", "non-git", journal.workspaceId), {
|
|
29255
29376
|
recursive: true
|
|
29256
29377
|
})
|
|
29257
29378
|
]);
|
|
29258
29379
|
await Promise.all([
|
|
29259
|
-
writeJson(
|
|
29260
|
-
writeJson(
|
|
29261
|
-
writeJson(
|
|
29380
|
+
writeJson(path53.join(stagingRoot, "schema.json"), manifest),
|
|
29381
|
+
writeJson(path53.join(stagingRoot, "shared", "config.json"), config),
|
|
29382
|
+
writeJson(path53.join(stagingRoot, "shared", "team", "policy.json"), policy),
|
|
29262
29383
|
writeJson(
|
|
29263
|
-
|
|
29384
|
+
path53.join(stagingRoot, "shared", "context", "project.json"),
|
|
29264
29385
|
projectFacts
|
|
29265
29386
|
),
|
|
29266
29387
|
writeJson(journalPath2(stagingRoot, journal.operationId), journal),
|
|
29267
29388
|
...privacy === null ? [] : [
|
|
29268
29389
|
writeJson(
|
|
29269
|
-
|
|
29390
|
+
path53.join(stagingRoot, PRIVACY_POLICY_FILE),
|
|
29270
29391
|
privacy.policy
|
|
29271
29392
|
),
|
|
29272
29393
|
writeJson(
|
|
29273
|
-
|
|
29394
|
+
path53.join(stagingRoot, PRIVACY_EXCLUSIONS_FILE),
|
|
29274
29395
|
privacy.exclusions
|
|
29275
29396
|
)
|
|
29276
29397
|
],
|
|
29277
29398
|
writeFile40(
|
|
29278
|
-
|
|
29399
|
+
path53.join(stagingRoot, ".gitignore"),
|
|
29279
29400
|
`${V3_IGNORE.join("\n")}
|
|
29280
29401
|
`,
|
|
29281
29402
|
{ encoding: "utf8", flag: "wx" }
|
|
@@ -29300,7 +29421,7 @@ async function readGreenfieldJournal(root, operationId) {
|
|
|
29300
29421
|
async function readManifest(root) {
|
|
29301
29422
|
try {
|
|
29302
29423
|
return parseSchemaManifest(
|
|
29303
|
-
JSON.parse(await readFile36(
|
|
29424
|
+
JSON.parse(await readFile36(path53.join(root, "schema.json"), "utf8"))
|
|
29304
29425
|
);
|
|
29305
29426
|
} catch (error) {
|
|
29306
29427
|
if (error instanceof SyntaxError || isNotFound26(error)) {
|
|
@@ -29332,11 +29453,11 @@ async function assertPrivacyMatchesJournal(root, manifest, journal) {
|
|
|
29332
29453
|
if (manifest.manifestVersion !== 3)
|
|
29333
29454
|
throw new Error("MANCODE_GREENFIELD_REPAIR_REQUIRED");
|
|
29334
29455
|
const policy = parsePrivacyPolicy(
|
|
29335
|
-
JSON.parse(await readFile36(
|
|
29456
|
+
JSON.parse(await readFile36(path53.join(root, PRIVACY_POLICY_FILE), "utf8"))
|
|
29336
29457
|
);
|
|
29337
29458
|
const exclusions = parsePrivacyExclusions(
|
|
29338
29459
|
JSON.parse(
|
|
29339
|
-
await readFile36(
|
|
29460
|
+
await readFile36(path53.join(root, PRIVACY_EXCLUSIONS_FILE), "utf8")
|
|
29340
29461
|
)
|
|
29341
29462
|
);
|
|
29342
29463
|
if (digestCanonicalJson(policy) !== journal.privacyPolicyDigest || manifest.privacyPolicy.digest !== journal.privacyPolicyDigest || manifest.privacyPolicy.revision !== policy.revision || policy.workspaceId !== journal.workspaceId || exclusions.workspaceId !== journal.workspaceId || policy.exclusions.revision !== exclusions.revision || policy.exclusions.digest !== digestCanonicalJson(exclusions))
|
|
@@ -29358,7 +29479,7 @@ async function readConfig(root) {
|
|
|
29358
29479
|
try {
|
|
29359
29480
|
config = parseProjectConfig(
|
|
29360
29481
|
JSON.parse(
|
|
29361
|
-
await readFile36(
|
|
29482
|
+
await readFile36(path53.join(root, "shared", "config.json"), "utf8")
|
|
29362
29483
|
)
|
|
29363
29484
|
);
|
|
29364
29485
|
} catch (error) {
|
|
@@ -29375,7 +29496,7 @@ async function readPolicy(root) {
|
|
|
29375
29496
|
policy = parseTeamPolicy(
|
|
29376
29497
|
JSON.parse(
|
|
29377
29498
|
await readFile36(
|
|
29378
|
-
|
|
29499
|
+
path53.join(root, "shared", "team", "policy.json"),
|
|
29379
29500
|
"utf8"
|
|
29380
29501
|
)
|
|
29381
29502
|
)
|
|
@@ -29393,7 +29514,7 @@ async function readProjectFactsAt(root) {
|
|
|
29393
29514
|
return parseProjectFacts(
|
|
29394
29515
|
JSON.parse(
|
|
29395
29516
|
await readFile36(
|
|
29396
|
-
|
|
29517
|
+
path53.join(root, "shared", "context", "project.json"),
|
|
29397
29518
|
"utf8"
|
|
29398
29519
|
)
|
|
29399
29520
|
)
|
|
@@ -29436,7 +29557,7 @@ function normalizeInput(input) {
|
|
|
29436
29557
|
parseSchemaManifest(manifest);
|
|
29437
29558
|
return {
|
|
29438
29559
|
...input,
|
|
29439
|
-
projectRoot:
|
|
29560
|
+
projectRoot: path53.resolve(input.projectRoot),
|
|
29440
29561
|
projectConfig: config,
|
|
29441
29562
|
teamPolicy: policy,
|
|
29442
29563
|
projectFacts: input.projectFacts === void 0 ? void 0 : parseProjectFacts(input.projectFacts)
|
|
@@ -29518,7 +29639,7 @@ function isAdapterRelativePathArray(value) {
|
|
|
29518
29639
|
(item) => typeof item === "string"
|
|
29519
29640
|
);
|
|
29520
29641
|
return paths.length === value.length && new Set(paths).size === paths.length && paths.every(
|
|
29521
|
-
(item) => item.trim() === item && item.length > 0 && !item.includes("\0") && !
|
|
29642
|
+
(item) => item.trim() === item && item.length > 0 && !item.includes("\0") && !path53.isAbsolute(item) && !/^[A-Za-z]:[\\/]/u.test(item) && !item.split(/[\\/]/u).some((segment) => segment === ".." || !segment)
|
|
29522
29643
|
);
|
|
29523
29644
|
}
|
|
29524
29645
|
function isAdapterLinkIdentityArray(value) {
|
|
@@ -29576,14 +29697,14 @@ function initializationProjectFacts(input, now) {
|
|
|
29576
29697
|
}
|
|
29577
29698
|
function journalPath2(root, operationId) {
|
|
29578
29699
|
assertUlid(operationId, "greenfield operationId");
|
|
29579
|
-
return
|
|
29700
|
+
return path53.join(root, JOURNAL_RELATIVE_DIRECTORY, `${operationId}.json`);
|
|
29580
29701
|
}
|
|
29581
29702
|
async function writeJson(target, value) {
|
|
29582
|
-
const directory =
|
|
29703
|
+
const directory = path53.dirname(target);
|
|
29583
29704
|
await mkdir32(directory, { recursive: true });
|
|
29584
|
-
const temporary =
|
|
29705
|
+
const temporary = path53.join(
|
|
29585
29706
|
directory,
|
|
29586
|
-
`.${
|
|
29707
|
+
`.${path53.basename(target)}.${process.pid}.${Date.now()}.tmp`
|
|
29587
29708
|
);
|
|
29588
29709
|
await writeFile40(temporary, `${JSON.stringify(value, null, 2)}
|
|
29589
29710
|
`, {
|
|
@@ -29704,9 +29825,9 @@ async function init(rootDir = process6.cwd(), options = {}) {
|
|
|
29704
29825
|
return EXIT_INIT_FAILED;
|
|
29705
29826
|
}
|
|
29706
29827
|
const authority = resolveInitAuthority(options);
|
|
29707
|
-
const mancodeDir =
|
|
29708
|
-
const stateFile =
|
|
29709
|
-
const v3SchemaFile =
|
|
29828
|
+
const mancodeDir = path54.join(rootDir, ".mancode");
|
|
29829
|
+
const stateFile = path54.join(mancodeDir, "state.json");
|
|
29830
|
+
const v3SchemaFile = path54.join(mancodeDir, "schema.json");
|
|
29710
29831
|
const wasInitialized = await pathExists6(stateFile);
|
|
29711
29832
|
let mutationSnapshots = [];
|
|
29712
29833
|
let directorySnapshots = [];
|
|
@@ -29785,7 +29906,7 @@ async function init(rootDir = process6.cwd(), options = {}) {
|
|
|
29785
29906
|
printNotProjectDirectory(rootDir, locale, "unsafe");
|
|
29786
29907
|
return EXIT_NOT_A_PROJECT_DIR;
|
|
29787
29908
|
}
|
|
29788
|
-
const isGitRepo = await pathExists6(
|
|
29909
|
+
const isGitRepo = await pathExists6(path54.join(rootDir, ".git"));
|
|
29789
29910
|
const hasEvidence = await hasProjectEvidence(rootDir);
|
|
29790
29911
|
let isGenericProject = false;
|
|
29791
29912
|
if (!isGitRepo && !hasEvidence) {
|
|
@@ -29902,8 +30023,8 @@ async function init(rootDir = process6.cwd(), options = {}) {
|
|
|
29902
30023
|
const managedFiles = getInitManagedFilePaths(rootDir, selectedPlatforms);
|
|
29903
30024
|
mutationSnapshots = await snapshotFiles(managedFiles);
|
|
29904
30025
|
directorySnapshots = await snapshotDirectories(managedFiles, [
|
|
29905
|
-
|
|
29906
|
-
|
|
30026
|
+
path54.join(mancodeDir, "workflows"),
|
|
30027
|
+
path54.join(mancodeDir, "preseason-reports")
|
|
29907
30028
|
]);
|
|
29908
30029
|
const team = await detectTeamStatus(rootDir);
|
|
29909
30030
|
const platformMinimal = Object.fromEntries(
|
|
@@ -29964,7 +30085,7 @@ async function init(rootDir = process6.cwd(), options = {}) {
|
|
|
29964
30085
|
`;
|
|
29965
30086
|
await fs4.writeFile(stateFile, stateContent, "utf-8");
|
|
29966
30087
|
await fs4.writeFile(
|
|
29967
|
-
|
|
30088
|
+
path54.join(mancodeDir, "project-profile.json"),
|
|
29968
30089
|
`${JSON.stringify(profile, null, 2)}
|
|
29969
30090
|
`,
|
|
29970
30091
|
"utf-8"
|
|
@@ -30001,7 +30122,7 @@ async function init(rootDir = process6.cwd(), options = {}) {
|
|
|
30001
30122
|
)
|
|
30002
30123
|
);
|
|
30003
30124
|
const tokens = await scanAesthetics(rootDir, uiLibrary);
|
|
30004
|
-
const tokensPath =
|
|
30125
|
+
const tokensPath = path54.join(
|
|
30005
30126
|
mancodeDir,
|
|
30006
30127
|
"aesthetics",
|
|
30007
30128
|
"style-tokens.json"
|
|
@@ -30165,7 +30286,7 @@ async function initializeV3(rootDir, options) {
|
|
|
30165
30286
|
);
|
|
30166
30287
|
return EXIT_INIT_FAILED;
|
|
30167
30288
|
}
|
|
30168
|
-
const schemaPath =
|
|
30289
|
+
const schemaPath = path54.join(rootDir, ".mancode", "schema.json");
|
|
30169
30290
|
let existingV3 = false;
|
|
30170
30291
|
let registeredAdapters = /* @__PURE__ */ new Set();
|
|
30171
30292
|
if (await pathExists6(schemaPath)) {
|
|
@@ -30309,7 +30430,7 @@ async function initializeV3(rootDir, options) {
|
|
|
30309
30430
|
} catch (error) {
|
|
30310
30431
|
if (scratchBackup !== null) {
|
|
30311
30432
|
console.error(
|
|
30312
|
-
` Previous .mancode scratch was preserved at ${
|
|
30433
|
+
` Previous .mancode scratch was preserved at ${path54.relative(rootDir, scratchBackup)}.`
|
|
30313
30434
|
);
|
|
30314
30435
|
}
|
|
30315
30436
|
printV3InitError(error);
|
|
@@ -30335,7 +30456,7 @@ async function resolveUnsafeInitAdapterPaths(rootDir, options, selectedPlatforms
|
|
|
30335
30456
|
if (fixable.length === 0) return null;
|
|
30336
30457
|
const writeThroughAvailable = found.length > 0 && (await Promise.all(
|
|
30337
30458
|
found.map(
|
|
30338
|
-
(entry) => writeThroughResolvedPath(
|
|
30459
|
+
(entry) => writeThroughResolvedPath(path54.resolve(rootDir), entry.target)
|
|
30339
30460
|
)
|
|
30340
30461
|
)).every((resolved) => resolved !== null);
|
|
30341
30462
|
const choice = await prompter.resolveUnsafeAdapterPaths({
|
|
@@ -30364,7 +30485,7 @@ async function resolveScratchMancodeTarget(rootDir, options) {
|
|
|
30364
30485
|
if (!inspection.v3ScratchOnly) {
|
|
30365
30486
|
return { exit: null, backupPath: null };
|
|
30366
30487
|
}
|
|
30367
|
-
const mancodeRoot =
|
|
30488
|
+
const mancodeRoot = path54.join(rootDir, ".mancode");
|
|
30368
30489
|
if (inspection.v3TargetEntries.length === 0) {
|
|
30369
30490
|
await fs4.rmdir(mancodeRoot);
|
|
30370
30491
|
console.log(
|
|
@@ -30387,39 +30508,39 @@ async function resolveScratchMancodeTarget(rootDir, options) {
|
|
|
30387
30508
|
);
|
|
30388
30509
|
return { exit: EXIT_USER_CANCEL, backupPath: null };
|
|
30389
30510
|
}
|
|
30390
|
-
const backupPath =
|
|
30511
|
+
const backupPath = path54.join(
|
|
30391
30512
|
rootDir,
|
|
30392
30513
|
`${SCRATCH_BACKUP_PREFIX}${randomUUID()}`
|
|
30393
30514
|
);
|
|
30394
30515
|
await fs4.rename(mancodeRoot, backupPath);
|
|
30395
30516
|
console.log(
|
|
30396
|
-
`\u2139\uFE0F Moved non-Continuity .mancode scratch aside: ${
|
|
30517
|
+
`\u2139\uFE0F Moved non-Continuity .mancode scratch aside: ${path54.relative(rootDir, backupPath)}`
|
|
30397
30518
|
);
|
|
30398
30519
|
return { exit: null, backupPath };
|
|
30399
30520
|
}
|
|
30400
30521
|
async function restoreScratchBackup(rootDir, backupPath) {
|
|
30401
|
-
const localTarget =
|
|
30402
|
-
const leftover =
|
|
30522
|
+
const localTarget = path54.join(rootDir, ".mancode", "local");
|
|
30523
|
+
const leftover = path54.relative(rootDir, backupPath);
|
|
30403
30524
|
try {
|
|
30404
30525
|
await fs4.mkdir(localTarget, { recursive: true });
|
|
30405
30526
|
const entries = await fs4.readdir(backupPath, { withFileTypes: true });
|
|
30406
30527
|
for (const entry of entries) {
|
|
30407
|
-
const source =
|
|
30528
|
+
const source = path54.join(backupPath, entry.name);
|
|
30408
30529
|
if (entry.isDirectory() && entry.name === "local") {
|
|
30409
30530
|
for (const child of await fs4.readdir(source)) {
|
|
30410
|
-
const destination =
|
|
30531
|
+
const destination = path54.join(localTarget, child);
|
|
30411
30532
|
if (await pathExists6(destination)) continue;
|
|
30412
|
-
await fs4.rename(
|
|
30533
|
+
await fs4.rename(path54.join(source, child), destination);
|
|
30413
30534
|
}
|
|
30414
30535
|
} else {
|
|
30415
|
-
const preinitScratch =
|
|
30536
|
+
const preinitScratch = path54.join(localTarget, "preinit-scratch");
|
|
30416
30537
|
await fs4.mkdir(preinitScratch, { recursive: true });
|
|
30417
|
-
const destination =
|
|
30538
|
+
const destination = path54.join(preinitScratch, entry.name);
|
|
30418
30539
|
if (await pathExists6(destination)) continue;
|
|
30419
30540
|
await fs4.rename(source, destination);
|
|
30420
30541
|
}
|
|
30421
30542
|
}
|
|
30422
|
-
await fs4.rmdir(
|
|
30543
|
+
await fs4.rmdir(path54.join(backupPath, "local")).catch(() => void 0);
|
|
30423
30544
|
await fs4.rmdir(backupPath).catch(() => void 0);
|
|
30424
30545
|
if (await pathExists6(backupPath)) {
|
|
30425
30546
|
console.warn(
|
|
@@ -30460,7 +30581,7 @@ function printV3InitError(error) {
|
|
|
30460
30581
|
}
|
|
30461
30582
|
}
|
|
30462
30583
|
async function updateConfigOptions(mancodeDir, patch, preserveInstalledPlatforms) {
|
|
30463
|
-
const configPath =
|
|
30584
|
+
const configPath = path54.join(mancodeDir, "config.json");
|
|
30464
30585
|
let config = {};
|
|
30465
30586
|
try {
|
|
30466
30587
|
config = JSON.parse(await fs4.readFile(configPath, "utf-8"));
|
|
@@ -30493,7 +30614,7 @@ async function updateConfigOptions(mancodeDir, patch, preserveInstalledPlatforms
|
|
|
30493
30614
|
async function readExistingInitPreferences(mancodeDir) {
|
|
30494
30615
|
try {
|
|
30495
30616
|
const config = JSON.parse(
|
|
30496
|
-
await fs4.readFile(
|
|
30617
|
+
await fs4.readFile(path54.join(mancodeDir, "config.json"), "utf-8")
|
|
30497
30618
|
);
|
|
30498
30619
|
const preferences = {
|
|
30499
30620
|
platforms: Array.isArray(config.platforms) ? config.platforms.filter(
|
|
@@ -30558,8 +30679,8 @@ async function selectInitPlatforms(input) {
|
|
|
30558
30679
|
return [DEFAULT_INIT_PLATFORM];
|
|
30559
30680
|
}
|
|
30560
30681
|
async function canInitializeGenericProject(rootDir) {
|
|
30561
|
-
const resolved =
|
|
30562
|
-
if (resolved ===
|
|
30682
|
+
const resolved = path54.resolve(rootDir);
|
|
30683
|
+
if (resolved === path54.parse(resolved).root || resolved === path54.resolve(os.homedir())) {
|
|
30563
30684
|
return { ok: false, reason: "unsafe" };
|
|
30564
30685
|
}
|
|
30565
30686
|
try {
|
|
@@ -30578,7 +30699,7 @@ async function validateV3CliProjectBoundary(rootDir, options, locale, legacyInit
|
|
|
30578
30699
|
printNotProjectDirectory(rootDir, locale, "unsafe");
|
|
30579
30700
|
return EXIT_NOT_A_PROJECT_DIR;
|
|
30580
30701
|
}
|
|
30581
|
-
const isGitRepo = await pathExists6(
|
|
30702
|
+
const isGitRepo = await pathExists6(path54.join(rootDir, ".git"));
|
|
30582
30703
|
const hasEvidence = await hasProjectEvidence(rootDir);
|
|
30583
30704
|
if (isGitRepo || hasEvidence) return null;
|
|
30584
30705
|
const inspection = await inspectMancodeLayout(rootDir);
|
|
@@ -30724,7 +30845,7 @@ function getInitManagedFilePaths(rootDir, platforms) {
|
|
|
30724
30845
|
files.push(`.github/prompts/${mode}.prompt.md`);
|
|
30725
30846
|
}
|
|
30726
30847
|
}
|
|
30727
|
-
return [...new Set(files.map((file) =>
|
|
30848
|
+
return [...new Set(files.map((file) => path54.join(rootDir, file)))];
|
|
30728
30849
|
}
|
|
30729
30850
|
async function snapshotFiles(filePaths) {
|
|
30730
30851
|
return Promise.all(
|
|
@@ -30743,10 +30864,10 @@ async function snapshotFiles(filePaths) {
|
|
|
30743
30864
|
async function snapshotDirectories(filePaths, additionalDirectories = []) {
|
|
30744
30865
|
const directories = new Set(additionalDirectories);
|
|
30745
30866
|
for (const filePath of filePaths) {
|
|
30746
|
-
let current =
|
|
30747
|
-
while (current !==
|
|
30867
|
+
let current = path54.dirname(filePath);
|
|
30868
|
+
while (current !== path54.dirname(current)) {
|
|
30748
30869
|
directories.add(current);
|
|
30749
|
-
current =
|
|
30870
|
+
current = path54.dirname(current);
|
|
30750
30871
|
}
|
|
30751
30872
|
}
|
|
30752
30873
|
return Promise.all(
|
|
@@ -30762,7 +30883,7 @@ async function restoreFiles(snapshots) {
|
|
|
30762
30883
|
await fs4.rm(snapshot.filePath, { force: true });
|
|
30763
30884
|
continue;
|
|
30764
30885
|
}
|
|
30765
|
-
await fs4.mkdir(
|
|
30886
|
+
await fs4.mkdir(path54.dirname(snapshot.filePath), { recursive: true });
|
|
30766
30887
|
await fs4.writeFile(snapshot.filePath, snapshot.content, "utf-8");
|
|
30767
30888
|
}
|
|
30768
30889
|
}
|
|
@@ -30846,15 +30967,15 @@ async function pathExists6(p) {
|
|
|
30846
30967
|
|
|
30847
30968
|
// src/commands/install.ts
|
|
30848
30969
|
import { promises as fs5 } from "fs";
|
|
30849
|
-
import
|
|
30970
|
+
import path55 from "path";
|
|
30850
30971
|
import process7 from "process";
|
|
30851
30972
|
var EXIT_OK3 = 0;
|
|
30852
30973
|
var EXIT_NOT_INITIALIZED2 = 1;
|
|
30853
30974
|
var EXIT_UNSUPPORTED_PLATFORM = 2;
|
|
30854
30975
|
var EXIT_INSTALL_FAILED = 3;
|
|
30855
30976
|
async function install(rootDir = process7.cwd(), platform = "claude-code", options = {}) {
|
|
30856
|
-
const stateFile =
|
|
30857
|
-
const v3SchemaFile =
|
|
30977
|
+
const stateFile = path55.join(rootDir, ".mancode", "state.json");
|
|
30978
|
+
const v3SchemaFile = path55.join(rootDir, ".mancode", "schema.json");
|
|
30858
30979
|
if (await pathExists7(v3SchemaFile)) {
|
|
30859
30980
|
return installV3(rootDir, platform, options);
|
|
30860
30981
|
}
|
|
@@ -31015,7 +31136,7 @@ function printUnsupportedPlatform(platform) {
|
|
|
31015
31136
|
}
|
|
31016
31137
|
}
|
|
31017
31138
|
async function readConfig2(rootDir) {
|
|
31018
|
-
const configPath =
|
|
31139
|
+
const configPath = path55.join(rootDir, ".mancode", "config.json");
|
|
31019
31140
|
try {
|
|
31020
31141
|
const raw = await fs5.readFile(configPath, "utf-8");
|
|
31021
31142
|
return { config: JSON.parse(raw), valid: true };
|
|
@@ -31030,7 +31151,7 @@ function isNodeError8(err) {
|
|
|
31030
31151
|
return err instanceof Error && "code" in err;
|
|
31031
31152
|
}
|
|
31032
31153
|
async function updateConfig(rootDir, config) {
|
|
31033
|
-
const configPath =
|
|
31154
|
+
const configPath = path55.join(rootDir, ".mancode", "config.json");
|
|
31034
31155
|
const content = `${JSON.stringify(config, null, 2)}
|
|
31035
31156
|
`;
|
|
31036
31157
|
await fs5.writeFile(configPath, content, "utf-8");
|
|
@@ -31066,7 +31187,7 @@ function readConfiguredMinimal(value, platform) {
|
|
|
31066
31187
|
async function readStatePlatform(rootDir) {
|
|
31067
31188
|
try {
|
|
31068
31189
|
const raw = await fs5.readFile(
|
|
31069
|
-
|
|
31190
|
+
path55.join(rootDir, ".mancode", "state.json"),
|
|
31070
31191
|
"utf-8"
|
|
31071
31192
|
);
|
|
31072
31193
|
const state = JSON.parse(raw);
|
|
@@ -31089,11 +31210,11 @@ function isRecord9(value) {
|
|
|
31089
31210
|
|
|
31090
31211
|
// src/commands/list-platforms.ts
|
|
31091
31212
|
import { promises as fs6 } from "fs";
|
|
31092
|
-
import
|
|
31213
|
+
import path56 from "path";
|
|
31093
31214
|
import process8 from "process";
|
|
31094
31215
|
var EXIT_OK4 = 0;
|
|
31095
31216
|
async function listPlatforms(rootDir = process8.cwd()) {
|
|
31096
|
-
if (await pathExists8(
|
|
31217
|
+
if (await pathExists8(path56.join(rootDir, ".mancode", "schema.json"))) {
|
|
31097
31218
|
return listV3Platforms(rootDir);
|
|
31098
31219
|
}
|
|
31099
31220
|
const installed = new Set(await readInstalledPlatforms(rootDir));
|
|
@@ -31129,7 +31250,7 @@ async function listV3Platforms(rootDir) {
|
|
|
31129
31250
|
async function readInstalledPlatforms(rootDir) {
|
|
31130
31251
|
try {
|
|
31131
31252
|
const raw = await fs6.readFile(
|
|
31132
|
-
|
|
31253
|
+
path56.join(rootDir, ".mancode", "config.json"),
|
|
31133
31254
|
"utf-8"
|
|
31134
31255
|
);
|
|
31135
31256
|
const config = JSON.parse(raw);
|
|
@@ -31162,7 +31283,7 @@ function describePlatform(platform) {
|
|
|
31162
31283
|
|
|
31163
31284
|
// src/commands/manps.ts
|
|
31164
31285
|
import { access as access4, readFile as readFile38 } from "fs/promises";
|
|
31165
|
-
import
|
|
31286
|
+
import path58 from "path";
|
|
31166
31287
|
import { createInterface as createInterface2 } from "readline/promises";
|
|
31167
31288
|
|
|
31168
31289
|
// src/system/preseason.ts
|
|
@@ -31178,7 +31299,7 @@ import {
|
|
|
31178
31299
|
rename as rename10,
|
|
31179
31300
|
writeFile as writeFile41
|
|
31180
31301
|
} from "fs/promises";
|
|
31181
|
-
import
|
|
31302
|
+
import path57 from "path";
|
|
31182
31303
|
var PRESEASON_AREAS = [
|
|
31183
31304
|
"all",
|
|
31184
31305
|
"deps",
|
|
@@ -31258,10 +31379,10 @@ async function runPreseasonScan(projectRoot, area = "all", options = {}) {
|
|
|
31258
31379
|
const needsFiles = normalizedArea === "all" || normalizedArea === "dead-code" || normalizedArea === "config";
|
|
31259
31380
|
const files = needsFiles ? await listProjectFiles(projectRoot) : [];
|
|
31260
31381
|
const issues = (await scanArea(projectRoot, normalizedArea, pkg, files)).slice(0, 20);
|
|
31261
|
-
const storageRoot = options.storageRoot ??
|
|
31262
|
-
const reportDir =
|
|
31382
|
+
const storageRoot = options.storageRoot ?? path57.join(projectRoot, ".mancode");
|
|
31383
|
+
const reportDir = path57.join(storageRoot, "preseason-reports");
|
|
31263
31384
|
await mkdir33(reportDir, { recursive: true });
|
|
31264
|
-
const issueDbPath =
|
|
31385
|
+
const issueDbPath = path57.join(storageRoot, "preseason-issues.json");
|
|
31265
31386
|
const reportPath = await allocateReportPath(
|
|
31266
31387
|
reportDir,
|
|
31267
31388
|
`${generatedAt.replace(/[:.]/g, "-")}-${normalizedArea}`
|
|
@@ -31277,7 +31398,7 @@ async function runPreseasonScan(projectRoot, area = "all", options = {}) {
|
|
|
31277
31398
|
const database = await buildIssueDatabase(projectRoot, report);
|
|
31278
31399
|
await writeFile41(reportPath, renderPreseasonReport(report), "utf-8");
|
|
31279
31400
|
await writeFile41(
|
|
31280
|
-
|
|
31401
|
+
path57.join(storageRoot, "preseason-report.md"),
|
|
31281
31402
|
renderPreseasonReport(report),
|
|
31282
31403
|
"utf-8"
|
|
31283
31404
|
);
|
|
@@ -31285,7 +31406,7 @@ async function runPreseasonScan(projectRoot, area = "all", options = {}) {
|
|
|
31285
31406
|
return report;
|
|
31286
31407
|
}
|
|
31287
31408
|
async function runPreseasonRemediation(projectRoot, issues, options = {}) {
|
|
31288
|
-
const issueDbPath = options.issueDbPath ??
|
|
31409
|
+
const issueDbPath = options.issueDbPath ?? path57.join(projectRoot, ".mancode", "preseason-issues.json");
|
|
31289
31410
|
const database = await readIssueDatabase(issueDbPath);
|
|
31290
31411
|
const keys = new Set(issues.map((issue) => issueKey(issue)));
|
|
31291
31412
|
const targets = database.issues.filter(
|
|
@@ -31395,7 +31516,7 @@ async function scanArea(projectRoot, area, pkg, files) {
|
|
|
31395
31516
|
async function allocateReportPath(reportDir, baseName) {
|
|
31396
31517
|
for (let attempt = 0; attempt < 1e3; attempt++) {
|
|
31397
31518
|
const suffix = attempt === 0 ? "" : `-${attempt + 1}`;
|
|
31398
|
-
const candidate =
|
|
31519
|
+
const candidate = path57.join(reportDir, `${baseName}${suffix}.md`);
|
|
31399
31520
|
if (!existsSync(candidate)) return candidate;
|
|
31400
31521
|
}
|
|
31401
31522
|
throw new Error(`unable to allocate preseason report path: ${baseName}`);
|
|
@@ -31444,8 +31565,8 @@ async function walk(root, current, results, depth) {
|
|
|
31444
31565
|
}
|
|
31445
31566
|
for (const entry of entries) {
|
|
31446
31567
|
if (IGNORE_DIRS.has(entry)) continue;
|
|
31447
|
-
const abs =
|
|
31448
|
-
const rel =
|
|
31568
|
+
const abs = path57.join(current, entry);
|
|
31569
|
+
const rel = path57.relative(root, abs);
|
|
31449
31570
|
let info;
|
|
31450
31571
|
try {
|
|
31451
31572
|
info = await lstat22(abs);
|
|
@@ -31455,7 +31576,7 @@ async function walk(root, current, results, depth) {
|
|
|
31455
31576
|
if (info.isSymbolicLink()) continue;
|
|
31456
31577
|
if (info.isDirectory()) {
|
|
31457
31578
|
await walk(root, abs, results, depth + 1);
|
|
31458
|
-
} else if (SOURCE_EXTENSIONS.has(
|
|
31579
|
+
} else if (SOURCE_EXTENSIONS.has(path57.extname(entry)) || entry === "package.json") {
|
|
31459
31580
|
results.push(rel);
|
|
31460
31581
|
if (results.length >= MAX_PROJECT_FILES) return;
|
|
31461
31582
|
}
|
|
@@ -31463,7 +31584,7 @@ async function walk(root, current, results, depth) {
|
|
|
31463
31584
|
}
|
|
31464
31585
|
async function readPackageJson(projectRoot) {
|
|
31465
31586
|
try {
|
|
31466
|
-
const raw = await readFile37(
|
|
31587
|
+
const raw = await readFile37(path57.join(projectRoot, "package.json"), "utf-8");
|
|
31467
31588
|
return JSON.parse(raw);
|
|
31468
31589
|
} catch {
|
|
31469
31590
|
return null;
|
|
@@ -31556,7 +31677,7 @@ function scanTodos(projectRoot, files) {
|
|
|
31556
31677
|
const matches = [];
|
|
31557
31678
|
for (const file of files) {
|
|
31558
31679
|
if (matches.length >= 7) break;
|
|
31559
|
-
const abs =
|
|
31680
|
+
const abs = path57.join(projectRoot, file);
|
|
31560
31681
|
matches.push(...readTodoIssues(abs, file, matches.length));
|
|
31561
31682
|
}
|
|
31562
31683
|
return matches.slice(0, 7);
|
|
@@ -31597,7 +31718,7 @@ function scanTestGaps(files) {
|
|
|
31597
31718
|
if (sourceFiles.length === 0) return [];
|
|
31598
31719
|
const tests = new Set(files.filter((file) => file.startsWith("tests/")));
|
|
31599
31720
|
const missing = sourceFiles.filter((file) => {
|
|
31600
|
-
const base =
|
|
31721
|
+
const base = path57.basename(file).replace(/\.(ts|tsx|js|jsx)$/, "");
|
|
31601
31722
|
return !Array.from(tests).some((test) => test.includes(base));
|
|
31602
31723
|
}).slice(0, 4);
|
|
31603
31724
|
return missing.map((file, index) => ({
|
|
@@ -31606,13 +31727,13 @@ function scanTestGaps(files) {
|
|
|
31606
31727
|
type: "tests",
|
|
31607
31728
|
title: "Core source file has no obvious test",
|
|
31608
31729
|
file,
|
|
31609
|
-
detail: `No matching test file was found for ${
|
|
31730
|
+
detail: `No matching test file was found for ${path57.basename(file)}.`,
|
|
31610
31731
|
recommendation: "Add focused coverage for the public behavior or document why this module is exercised indirectly."
|
|
31611
31732
|
}));
|
|
31612
31733
|
}
|
|
31613
31734
|
function scanConfig(projectRoot, files) {
|
|
31614
31735
|
const issues = [];
|
|
31615
|
-
if (!files.includes(".gitignore") && !pathExistsSync(
|
|
31736
|
+
if (!files.includes(".gitignore") && !pathExistsSync(path57.join(projectRoot, ".gitignore"))) {
|
|
31616
31737
|
issues.push({
|
|
31617
31738
|
id: "config-gitignore",
|
|
31618
31739
|
severity: "P1",
|
|
@@ -31623,7 +31744,7 @@ function scanConfig(projectRoot, files) {
|
|
|
31623
31744
|
recommendation: "Add a .gitignore that excludes dependencies, build output, coverage, and local env files."
|
|
31624
31745
|
});
|
|
31625
31746
|
}
|
|
31626
|
-
if (!files.includes(".editorconfig") && !pathExistsSync(
|
|
31747
|
+
if (!files.includes(".editorconfig") && !pathExistsSync(path57.join(projectRoot, ".editorconfig"))) {
|
|
31627
31748
|
issues.push({
|
|
31628
31749
|
id: "config-editorconfig",
|
|
31629
31750
|
severity: "P2",
|
|
@@ -31642,7 +31763,7 @@ function scanAestheticDrift(projectRoot, files, pkg) {
|
|
|
31642
31763
|
for (const file of frontendFiles) {
|
|
31643
31764
|
let content;
|
|
31644
31765
|
try {
|
|
31645
|
-
content = readFileSyncSafe(
|
|
31766
|
+
content = readFileSyncSafe(path57.join(projectRoot, file));
|
|
31646
31767
|
} catch {
|
|
31647
31768
|
continue;
|
|
31648
31769
|
}
|
|
@@ -31693,7 +31814,7 @@ function detectedIconSystems(pkg) {
|
|
|
31693
31814
|
return systems.filter(([, pattern]) => packages.some((name) => pattern.test(name))).map(([name]) => name);
|
|
31694
31815
|
}
|
|
31695
31816
|
async function scanArchitecture(projectRoot) {
|
|
31696
|
-
const localBinary =
|
|
31817
|
+
const localBinary = path57.join(
|
|
31697
31818
|
projectRoot,
|
|
31698
31819
|
"node_modules",
|
|
31699
31820
|
".bin",
|
|
@@ -31741,7 +31862,7 @@ async function hasDependencyCruiserConfig(projectRoot) {
|
|
|
31741
31862
|
"dependency-cruiser.config.mjs"
|
|
31742
31863
|
];
|
|
31743
31864
|
const results = await Promise.all(
|
|
31744
|
-
files.map((file) => pathExists9(
|
|
31865
|
+
files.map((file) => pathExists9(path57.join(projectRoot, file)))
|
|
31745
31866
|
);
|
|
31746
31867
|
return results.some(Boolean);
|
|
31747
31868
|
}
|
|
@@ -31847,9 +31968,9 @@ function inferCommands(pkg) {
|
|
|
31847
31968
|
return ["lint", "test", "build"].filter((name) => scripts[name]).map((name) => `npm run ${name}`);
|
|
31848
31969
|
}
|
|
31849
31970
|
async function buildIssueDatabase(projectRoot, report) {
|
|
31850
|
-
const reportRef =
|
|
31971
|
+
const reportRef = path57.relative(projectRoot, report.reportPath);
|
|
31851
31972
|
const run = {
|
|
31852
|
-
id:
|
|
31973
|
+
id: path57.basename(report.reportPath, ".md"),
|
|
31853
31974
|
generatedAt: report.generatedAt,
|
|
31854
31975
|
area: report.area,
|
|
31855
31976
|
reportPath: reportRef,
|
|
@@ -31955,7 +32076,7 @@ function compareIssueRecords(a, b) {
|
|
|
31955
32076
|
}
|
|
31956
32077
|
async function applySafeRemediation(projectRoot, issue) {
|
|
31957
32078
|
if (issue.id === "config-gitignore" && issue.file === ".gitignore") {
|
|
31958
|
-
const gitignorePath =
|
|
32079
|
+
const gitignorePath = path57.join(projectRoot, ".gitignore");
|
|
31959
32080
|
if (pathExistsSync(gitignorePath)) {
|
|
31960
32081
|
return { applied: false };
|
|
31961
32082
|
}
|
|
@@ -31964,7 +32085,7 @@ async function applySafeRemediation(projectRoot, issue) {
|
|
|
31964
32085
|
return { applied: true, action: "created .gitignore" };
|
|
31965
32086
|
}
|
|
31966
32087
|
if (issue.id === "config-editorconfig" && issue.file === ".editorconfig") {
|
|
31967
|
-
const editorconfigPath =
|
|
32088
|
+
const editorconfigPath = path57.join(projectRoot, ".editorconfig");
|
|
31968
32089
|
if (pathExistsSync(editorconfigPath)) {
|
|
31969
32090
|
return { applied: false };
|
|
31970
32091
|
}
|
|
@@ -32004,7 +32125,7 @@ async function inferSafePackageScript(projectRoot, scriptName) {
|
|
|
32004
32125
|
}
|
|
32005
32126
|
}
|
|
32006
32127
|
async function addPackageScript(projectRoot, scriptName, script) {
|
|
32007
|
-
const packagePath =
|
|
32128
|
+
const packagePath = path57.join(projectRoot, "package.json");
|
|
32008
32129
|
let pkg;
|
|
32009
32130
|
try {
|
|
32010
32131
|
pkg = JSON.parse(await readFile37(packagePath, "utf-8"));
|
|
@@ -32117,7 +32238,7 @@ var EXIT_NOT_INITIALIZED3 = 1;
|
|
|
32117
32238
|
var EXIT_SCAN_FAILED = 2;
|
|
32118
32239
|
var EXIT_INVALID_ARG = 3;
|
|
32119
32240
|
async function manps(rootDir, area = "all", options = {}) {
|
|
32120
|
-
const v3SchemaPath =
|
|
32241
|
+
const v3SchemaPath = path58.join(rootDir, ".mancode", "schema.json");
|
|
32121
32242
|
const v3Activation = await readV3ActivationState(v3SchemaPath);
|
|
32122
32243
|
if (v3Activation !== null && v3Activation !== "v3_active" && v3Activation !== "dual_read") {
|
|
32123
32244
|
const message = `manps is unavailable while mancode activation is ${v3Activation}`;
|
|
@@ -32130,7 +32251,7 @@ async function manps(rootDir, area = "all", options = {}) {
|
|
|
32130
32251
|
return EXIT_SCAN_FAILED;
|
|
32131
32252
|
}
|
|
32132
32253
|
const v3Initialized = v3Activation === "v3_active";
|
|
32133
|
-
const initialized = v3Initialized || await pathExists10(
|
|
32254
|
+
const initialized = v3Initialized || await pathExists10(path58.join(rootDir, ".mancode", "state.json"));
|
|
32134
32255
|
if (!initialized) {
|
|
32135
32256
|
if (options.json) {
|
|
32136
32257
|
console.log(JSON.stringify({ error: "not initialized" }, null, 2));
|
|
@@ -32143,7 +32264,7 @@ async function manps(rootDir, area = "all", options = {}) {
|
|
|
32143
32264
|
let report;
|
|
32144
32265
|
try {
|
|
32145
32266
|
report = await runPreseasonScan(rootDir, area, {
|
|
32146
|
-
storageRoot: v3Initialized ?
|
|
32267
|
+
storageRoot: v3Initialized ? path58.join(rootDir, ".mancode", "local") : void 0
|
|
32147
32268
|
});
|
|
32148
32269
|
} catch (err) {
|
|
32149
32270
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -32212,8 +32333,8 @@ async function manps(rootDir, area = "all", options = {}) {
|
|
|
32212
32333
|
console.log(
|
|
32213
32334
|
`Issues: ${report.issues.length} total (P0 ${p0}, P1 ${p1}, P2 ${p2})`
|
|
32214
32335
|
);
|
|
32215
|
-
console.log(`Report: ${
|
|
32216
|
-
console.log(`Issue DB: ${
|
|
32336
|
+
console.log(`Report: ${path58.relative(rootDir, report.reportPath)}`);
|
|
32337
|
+
console.log(`Issue DB: ${path58.relative(rootDir, report.issueDbPath)}`);
|
|
32217
32338
|
if (report.issues.length > 0) {
|
|
32218
32339
|
console.log("");
|
|
32219
32340
|
for (const issue of report.issues.slice(0, 7)) {
|
|
@@ -32229,7 +32350,7 @@ async function manps(rootDir, area = "all", options = {}) {
|
|
|
32229
32350
|
console.log(` Skipped: ${remediation.skipped}`);
|
|
32230
32351
|
console.log(` Fixed: ${remediation.fixed}`);
|
|
32231
32352
|
console.log(
|
|
32232
|
-
` Issue DB: ${
|
|
32353
|
+
` Issue DB: ${path58.relative(rootDir, remediation.issueDbPath)}`
|
|
32233
32354
|
);
|
|
32234
32355
|
}
|
|
32235
32356
|
return EXIT_OK5;
|
|
@@ -32300,7 +32421,7 @@ async function readV3ActivationState(schemaPath) {
|
|
|
32300
32421
|
|
|
32301
32422
|
// src/commands/migrate.ts
|
|
32302
32423
|
import { readFile as readFile39 } from "fs/promises";
|
|
32303
|
-
import
|
|
32424
|
+
import path59 from "path";
|
|
32304
32425
|
var EXIT_OK6 = 0;
|
|
32305
32426
|
var EXIT_INVALID_ARG2 = 2;
|
|
32306
32427
|
var EXIT_MIGRATION_BLOCKED = 3;
|
|
@@ -32453,9 +32574,9 @@ async function readScopeFile(rootDir, file) {
|
|
|
32453
32574
|
if (!file.trim() || file.includes("\0")) {
|
|
32454
32575
|
throw new Error("MANCODE_MIGRATION_SCOPE_FILE_INVALID");
|
|
32455
32576
|
}
|
|
32456
|
-
const resolved =
|
|
32457
|
-
const relative =
|
|
32458
|
-
if (relative === ".." || relative.startsWith(`..${
|
|
32577
|
+
const resolved = path59.resolve(rootDir, file);
|
|
32578
|
+
const relative = path59.relative(path59.resolve(rootDir), resolved);
|
|
32579
|
+
if (relative === ".." || relative.startsWith(`..${path59.sep}`) || path59.isAbsolute(relative)) {
|
|
32459
32580
|
throw new Error("MANCODE_MIGRATION_SCOPE_FILE_INVALID");
|
|
32460
32581
|
}
|
|
32461
32582
|
try {
|
|
@@ -32574,7 +32695,7 @@ async function runOperationMutation(rootDir, operationId, options, mode) {
|
|
|
32574
32695
|
// src/commands/privacy.ts
|
|
32575
32696
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
32576
32697
|
import { constants, promises as fs7 } from "fs";
|
|
32577
|
-
import
|
|
32698
|
+
import path62 from "path";
|
|
32578
32699
|
|
|
32579
32700
|
// src/privacy/redact.ts
|
|
32580
32701
|
function mergeSensitiveSpans(findings) {
|
|
@@ -32623,11 +32744,11 @@ function redactSensitiveText(value, ruleIds) {
|
|
|
32623
32744
|
|
|
32624
32745
|
// src/commands/privacy-policy.ts
|
|
32625
32746
|
import { lstat as lstat24, readFile as readFile40 } from "fs/promises";
|
|
32626
|
-
import
|
|
32747
|
+
import path61 from "path";
|
|
32627
32748
|
|
|
32628
32749
|
// src/context/privacy-policy-operation.ts
|
|
32629
32750
|
import { lstat as lstat23, rm as rm20, writeFile as writeFile42 } from "fs/promises";
|
|
32630
|
-
import
|
|
32751
|
+
import path60 from "path";
|
|
32631
32752
|
var OPERATION = "privacy_policy_update";
|
|
32632
32753
|
async function readPrivacyPolicyOperationTarget(root, operationId) {
|
|
32633
32754
|
const runtime = await readProjectRuntimeContext(root);
|
|
@@ -32690,7 +32811,7 @@ async function previewPrivacyPolicyUpdate(input) {
|
|
|
32690
32811
|
};
|
|
32691
32812
|
}
|
|
32692
32813
|
async function updatePrivacyPolicy(input) {
|
|
32693
|
-
const root =
|
|
32814
|
+
const root = path60.resolve(input.projectRoot);
|
|
32694
32815
|
const candidate = parsePrivacyPolicyCandidate(input.candidate);
|
|
32695
32816
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
32696
32817
|
const operationId = input.operationId ?? createUlid(now.getTime());
|
|
@@ -33030,15 +33151,15 @@ async function optionalContent(root, file) {
|
|
|
33030
33151
|
}
|
|
33031
33152
|
}
|
|
33032
33153
|
async function writeAuthority(root, relative, content, operationId) {
|
|
33033
|
-
const directory =
|
|
33034
|
-
const target =
|
|
33154
|
+
const directory = path60.join(root, ".mancode", path60.dirname(relative));
|
|
33155
|
+
const target = path60.join(root, ".mancode", relative);
|
|
33035
33156
|
await optionalContent(root, relative);
|
|
33036
33157
|
const parent = await lstat23(directory);
|
|
33037
33158
|
if (!parent.isDirectory() || parent.isSymbolicLink())
|
|
33038
33159
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
33039
|
-
const temporary =
|
|
33160
|
+
const temporary = path60.join(
|
|
33040
33161
|
directory,
|
|
33041
|
-
`.${
|
|
33162
|
+
`.${path60.basename(relative)}.${operationId}.tmp`
|
|
33042
33163
|
);
|
|
33043
33164
|
await writeFile42(temporary, content, { encoding: "utf8", flag: "wx" });
|
|
33044
33165
|
try {
|
|
@@ -33109,7 +33230,7 @@ async function privacyPolicyCommand(root, options, enabled) {
|
|
|
33109
33230
|
if (enabled === void 0) {
|
|
33110
33231
|
if (options.file === void 0)
|
|
33111
33232
|
throw new Error("MANCODE_PRIVACY_CANDIDATE_REQUIRED");
|
|
33112
|
-
const file =
|
|
33233
|
+
const file = path61.resolve(options.file);
|
|
33113
33234
|
const stat5 = await lstat24(file);
|
|
33114
33235
|
if (!stat5.isFile() || stat5.isSymbolicLink() || stat5.size > 64 * 1024)
|
|
33115
33236
|
throw new Error("MANCODE_PRIVACY_CANDIDATE_INVALID");
|
|
@@ -33210,7 +33331,7 @@ async function readInput(rootDir, file, stdin2) {
|
|
|
33210
33331
|
let handle;
|
|
33211
33332
|
try {
|
|
33212
33333
|
handle = await fs7.open(
|
|
33213
|
-
|
|
33334
|
+
path62.resolve(rootDir, file),
|
|
33214
33335
|
constants.O_RDONLY | constants.O_NONBLOCK
|
|
33215
33336
|
);
|
|
33216
33337
|
const stat5 = await handle.stat();
|
|
@@ -33309,9 +33430,9 @@ async function privacyPreview(rootDir, options = {}, stdin2 = process.stdin) {
|
|
|
33309
33430
|
printReport(result2.scan, options);
|
|
33310
33431
|
return 2;
|
|
33311
33432
|
}
|
|
33312
|
-
const destination =
|
|
33313
|
-
const temporary =
|
|
33314
|
-
|
|
33433
|
+
const destination = path62.resolve(rootDir, options.output);
|
|
33434
|
+
const temporary = path62.join(
|
|
33435
|
+
path62.dirname(destination),
|
|
33315
33436
|
`.mancode-preview-${randomUUID2()}.tmp`
|
|
33316
33437
|
);
|
|
33317
33438
|
let handle;
|
|
@@ -33388,11 +33509,11 @@ function registerPrivacyCommands(program) {
|
|
|
33388
33509
|
|
|
33389
33510
|
// src/context/project-policy-upgrade.ts
|
|
33390
33511
|
import { lstat as lstat25, mkdir as mkdir34, readFile as readFile41, rm as rm21, writeFile as writeFile43 } from "fs/promises";
|
|
33391
|
-
import
|
|
33512
|
+
import path63 from "path";
|
|
33392
33513
|
var UPGRADE_OPERATION = "project_policy_upgrade";
|
|
33393
33514
|
async function dryRunProjectPolicyUpgrade(input) {
|
|
33394
33515
|
assertPolicyVersion(input.policyVersion);
|
|
33395
|
-
const root =
|
|
33516
|
+
const root = path63.resolve(input.projectRoot);
|
|
33396
33517
|
const project = await new V3ContextStore(root).readProjectSnapshot();
|
|
33397
33518
|
const beforeDigest = digestManifest(project.manifest);
|
|
33398
33519
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
@@ -33436,7 +33557,7 @@ async function dryRunProjectPolicyUpgrade(input) {
|
|
|
33436
33557
|
async function upgradeProjectPolicy(input) {
|
|
33437
33558
|
assertPolicyVersion(input.policyVersion);
|
|
33438
33559
|
assertUlid(input.sessionId, "project policy upgrade sessionId");
|
|
33439
|
-
const root =
|
|
33560
|
+
const root = path63.resolve(input.projectRoot);
|
|
33440
33561
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
33441
33562
|
const operationId = input.operationId;
|
|
33442
33563
|
if (operationId === void 0) {
|
|
@@ -33695,16 +33816,16 @@ function needsPlanningUpgrade(manifest) {
|
|
|
33695
33816
|
return !hasPlanningPolicy2(manifest);
|
|
33696
33817
|
}
|
|
33697
33818
|
async function readSchemaContent(root) {
|
|
33698
|
-
return readFile41(
|
|
33819
|
+
return readFile41(path63.join(root, ".mancode", "schema.json"), "utf8");
|
|
33699
33820
|
}
|
|
33700
33821
|
async function writeSchemaContent(root, operationId, content) {
|
|
33701
|
-
const directory =
|
|
33702
|
-
const target =
|
|
33822
|
+
const directory = path63.join(root, ".mancode");
|
|
33823
|
+
const target = path63.join(directory, "schema.json");
|
|
33703
33824
|
const stat5 = await lstat25(target);
|
|
33704
33825
|
if (!stat5.isFile() || stat5.isSymbolicLink()) {
|
|
33705
33826
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
33706
33827
|
}
|
|
33707
|
-
const temporary =
|
|
33828
|
+
const temporary = path63.join(
|
|
33708
33829
|
directory,
|
|
33709
33830
|
`.schema.json.${operationId}.${process.pid}.tmp`
|
|
33710
33831
|
);
|
|
@@ -33780,13 +33901,13 @@ async function releaseLocks3(locks) {
|
|
|
33780
33901
|
await Promise.allSettled([...locks].reverse().map((lock) => lock.release()));
|
|
33781
33902
|
}
|
|
33782
33903
|
function projectUpgradePreviewRoot(root, operationId) {
|
|
33783
|
-
return
|
|
33904
|
+
return path63.join(root, ".mancode", "staging", "project-upgrade", operationId);
|
|
33784
33905
|
}
|
|
33785
33906
|
async function stageProjectPolicyUpgrade(root, receipt, manifestContent) {
|
|
33786
33907
|
const directory = projectUpgradePreviewRoot(root, receipt.operationId);
|
|
33787
|
-
const receiptPath =
|
|
33788
|
-
const manifestPath =
|
|
33789
|
-
await mkdir34(
|
|
33908
|
+
const receiptPath = path63.join(directory, "preview.json");
|
|
33909
|
+
const manifestPath = path63.join(directory, "schema.json");
|
|
33910
|
+
await mkdir34(path63.dirname(directory), { recursive: true });
|
|
33790
33911
|
try {
|
|
33791
33912
|
await mkdir34(directory);
|
|
33792
33913
|
} catch (error) {
|
|
@@ -33813,8 +33934,8 @@ async function stageProjectPolicyUpgrade(root, receipt, manifestContent) {
|
|
|
33813
33934
|
async function assertProjectPolicyUpgradePreview(root, operationId, project) {
|
|
33814
33935
|
const directory = projectUpgradePreviewRoot(root, operationId);
|
|
33815
33936
|
const [receiptContent, manifestContent] = await Promise.all([
|
|
33816
|
-
readSafePreviewFile(
|
|
33817
|
-
readSafePreviewFile(
|
|
33937
|
+
readSafePreviewFile(path63.join(directory, "preview.json")),
|
|
33938
|
+
readSafePreviewFile(path63.join(directory, "schema.json"))
|
|
33818
33939
|
]);
|
|
33819
33940
|
let receipt;
|
|
33820
33941
|
try {
|
|
@@ -33930,16 +34051,16 @@ async function projectUpgrade(rootDir, options) {
|
|
|
33930
34051
|
// src/commands/refresh-project.ts
|
|
33931
34052
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
33932
34053
|
import { promises as fs8 } from "fs";
|
|
33933
|
-
import
|
|
34054
|
+
import path64 from "path";
|
|
33934
34055
|
import process9 from "process";
|
|
33935
34056
|
var EXIT_OK7 = 0;
|
|
33936
34057
|
var EXIT_NOT_INITIALIZED4 = 1;
|
|
33937
34058
|
var EXIT_CORRUPT_STATE = 2;
|
|
33938
34059
|
var EXIT_REFRESH_FAILED = 3;
|
|
33939
34060
|
async function refreshProject(rootDir = process9.cwd()) {
|
|
33940
|
-
const mancodeDir =
|
|
33941
|
-
const statePath =
|
|
33942
|
-
if (await pathExists11(
|
|
34061
|
+
const mancodeDir = path64.join(rootDir, ".mancode");
|
|
34062
|
+
const statePath = path64.join(mancodeDir, "state.json");
|
|
34063
|
+
if (await pathExists11(path64.join(mancodeDir, "schema.json"))) {
|
|
33943
34064
|
return refreshV3Project(rootDir);
|
|
33944
34065
|
}
|
|
33945
34066
|
if (!await pathExists11(statePath)) {
|
|
@@ -33958,12 +34079,12 @@ async function refreshProject(rootDir = process9.cwd()) {
|
|
|
33958
34079
|
const [profile, team, hasGit, hasEvidence] = await Promise.all([
|
|
33959
34080
|
detectProjectProfile(rootDir),
|
|
33960
34081
|
detectTeamStatus(rootDir),
|
|
33961
|
-
pathExists11(
|
|
34082
|
+
pathExists11(path64.join(rootDir, ".git")),
|
|
33962
34083
|
hasProjectEvidence(rootDir)
|
|
33963
34084
|
]);
|
|
33964
34085
|
const uiLibrary = primaryUiLibrary(profile);
|
|
33965
34086
|
const stack = [...profile.languages, ...profile.frameworks];
|
|
33966
|
-
const config = await readJson2(
|
|
34087
|
+
const config = await readJson2(path64.join(mancodeDir, "config.json"));
|
|
33967
34088
|
const configuredTeam = config.forceTeamMode === true ? true : config.teamMode === "on" ? true : config.teamMode === "off" ? false : team.isTeam;
|
|
33968
34089
|
const nextState = {
|
|
33969
34090
|
...state,
|
|
@@ -33975,7 +34096,7 @@ async function refreshProject(rootDir = process9.cwd()) {
|
|
|
33975
34096
|
};
|
|
33976
34097
|
await writeProjectFacts2(
|
|
33977
34098
|
statePath,
|
|
33978
|
-
|
|
34099
|
+
path64.join(mancodeDir, "project-profile.json"),
|
|
33979
34100
|
`${JSON.stringify(nextState, null, 2)}
|
|
33980
34101
|
`,
|
|
33981
34102
|
`${JSON.stringify(profile, null, 2)}
|
|
@@ -34102,9 +34223,9 @@ async function readOptionalText(filePath) {
|
|
|
34102
34223
|
}
|
|
34103
34224
|
}
|
|
34104
34225
|
function temporaryPath(filePath) {
|
|
34105
|
-
return
|
|
34106
|
-
|
|
34107
|
-
`.${
|
|
34226
|
+
return path64.join(
|
|
34227
|
+
path64.dirname(filePath),
|
|
34228
|
+
`.${path64.basename(filePath)}.${process9.pid}.${randomUUID3()}.tmp`
|
|
34108
34229
|
);
|
|
34109
34230
|
}
|
|
34110
34231
|
async function refreshStaticPlatforms(rootDir, config, fallbackPlatform, stack, uiLibrary, profile) {
|
|
@@ -34174,7 +34295,7 @@ async function pathExists11(filePath) {
|
|
|
34174
34295
|
|
|
34175
34296
|
// src/commands/refresh-style.ts
|
|
34176
34297
|
import { promises as fs9 } from "fs";
|
|
34177
|
-
import
|
|
34298
|
+
import path65 from "path";
|
|
34178
34299
|
import process10 from "process";
|
|
34179
34300
|
var EXIT_OK8 = 0;
|
|
34180
34301
|
var EXIT_NOT_INITIALIZED5 = 1;
|
|
@@ -34185,8 +34306,8 @@ async function refreshStyle(rootDir = process10.cwd(), options = {}) {
|
|
|
34185
34306
|
console.error("\u2717 style scan root must stay inside the project root.");
|
|
34186
34307
|
return EXIT_V3_REFRESH_FAILED;
|
|
34187
34308
|
}
|
|
34188
|
-
const stateFile =
|
|
34189
|
-
if (await pathExists12(
|
|
34309
|
+
const stateFile = path65.join(rootDir, ".mancode", "state.json");
|
|
34310
|
+
if (await pathExists12(path65.join(rootDir, ".mancode", "schema.json"))) {
|
|
34190
34311
|
return refreshV3Style(rootDir, scanTarget.root, scanTarget.scopeRoot);
|
|
34191
34312
|
}
|
|
34192
34313
|
if (!await pathExists12(stateFile)) {
|
|
@@ -34196,7 +34317,7 @@ async function refreshStyle(rootDir = process10.cwd(), options = {}) {
|
|
|
34196
34317
|
}
|
|
34197
34318
|
console.log("\u2713 \u5237\u65B0\u9879\u76EE profile...");
|
|
34198
34319
|
const profile = await detectProjectProfile(rootDir);
|
|
34199
|
-
const profilePath =
|
|
34320
|
+
const profilePath = path65.join(rootDir, ".mancode", "project-profile.json");
|
|
34200
34321
|
await fs9.writeFile(
|
|
34201
34322
|
profilePath,
|
|
34202
34323
|
`${JSON.stringify(profile, null, 2)}
|
|
@@ -34223,13 +34344,13 @@ async function refreshStyle(rootDir = process10.cwd(), options = {}) {
|
|
|
34223
34344
|
uiLibraryHint,
|
|
34224
34345
|
scanTarget.scopeRoot
|
|
34225
34346
|
);
|
|
34226
|
-
const tokensPath =
|
|
34347
|
+
const tokensPath = path65.join(
|
|
34227
34348
|
rootDir,
|
|
34228
34349
|
".mancode",
|
|
34229
34350
|
"aesthetics",
|
|
34230
34351
|
"style-tokens.json"
|
|
34231
34352
|
);
|
|
34232
|
-
await fs9.mkdir(
|
|
34353
|
+
await fs9.mkdir(path65.dirname(tokensPath), { recursive: true });
|
|
34233
34354
|
await fs9.writeFile(
|
|
34234
34355
|
tokensPath,
|
|
34235
34356
|
`${JSON.stringify(tokens, null, 2)}
|
|
@@ -34302,7 +34423,7 @@ async function refreshV3Style(rootDir, scanRoot, scopeRoot) {
|
|
|
34302
34423
|
console.log(
|
|
34303
34424
|
` \u7C7B\u578B: ${profile.projectKind} | UI: ${profile.uiAssets} | \u6D4F\u89C8\u5668: ${profile.browserAutomation}`
|
|
34304
34425
|
);
|
|
34305
|
-
const tokensPath =
|
|
34426
|
+
const tokensPath = path65.join(
|
|
34306
34427
|
rootDir,
|
|
34307
34428
|
".mancode",
|
|
34308
34429
|
"local",
|
|
@@ -34319,7 +34440,7 @@ async function refreshV3Style(rootDir, scanRoot, scopeRoot) {
|
|
|
34319
34440
|
}
|
|
34320
34441
|
console.log("\u2713 \u626B\u63CF\u9879\u76EE\u8BBE\u8BA1 token...");
|
|
34321
34442
|
const tokens = await scanAesthetics(scanRoot, uiLibraryHint, scopeRoot);
|
|
34322
|
-
await fs9.mkdir(
|
|
34443
|
+
await fs9.mkdir(path65.dirname(tokensPath), { recursive: true });
|
|
34323
34444
|
await fs9.writeFile(
|
|
34324
34445
|
tokensPath,
|
|
34325
34446
|
`${JSON.stringify(tokens, null, 2)}
|
|
@@ -34353,7 +34474,7 @@ async function printStaticPlatformRefreshHint(rootDir) {
|
|
|
34353
34474
|
);
|
|
34354
34475
|
}
|
|
34355
34476
|
async function refreshLegacyStateContext(rootDir, profile, uiLibrary) {
|
|
34356
|
-
const statePath =
|
|
34477
|
+
const statePath = path65.join(rootDir, ".mancode", "state.json");
|
|
34357
34478
|
try {
|
|
34358
34479
|
const state = JSON.parse(await fs9.readFile(statePath, "utf-8"));
|
|
34359
34480
|
const stack = [...profile.languages, ...profile.frameworks];
|
|
@@ -34377,7 +34498,7 @@ async function refreshLegacyStateContext(rootDir, profile, uiLibrary) {
|
|
|
34377
34498
|
async function readInstalledPlatforms2(rootDir) {
|
|
34378
34499
|
try {
|
|
34379
34500
|
const raw = await fs9.readFile(
|
|
34380
|
-
|
|
34501
|
+
path65.join(rootDir, ".mancode", "config.json"),
|
|
34381
34502
|
"utf-8"
|
|
34382
34503
|
);
|
|
34383
34504
|
const config = JSON.parse(raw);
|
|
@@ -34397,30 +34518,30 @@ async function pathExists12(p) {
|
|
|
34397
34518
|
}
|
|
34398
34519
|
}
|
|
34399
34520
|
async function resolveScanTarget(rootDir, requestedRoot) {
|
|
34400
|
-
const projectRoot = await fs9.realpath(
|
|
34521
|
+
const projectRoot = await fs9.realpath(path65.resolve(rootDir)).catch(() => null);
|
|
34401
34522
|
if (projectRoot === null) return null;
|
|
34402
34523
|
if (requestedRoot === void 0 || requestedRoot === ".") {
|
|
34403
34524
|
return { root: projectRoot, scopeRoot: "." };
|
|
34404
34525
|
}
|
|
34405
|
-
if (
|
|
34526
|
+
if (path65.isAbsolute(requestedRoot) || requestedRoot.includes("\0") || requestedRoot.split(/[\\/]/).some((segment) => segment === "" || segment === "." || segment === "..")) {
|
|
34406
34527
|
return null;
|
|
34407
34528
|
}
|
|
34408
|
-
const candidate = await fs9.realpath(
|
|
34529
|
+
const candidate = await fs9.realpath(path65.resolve(projectRoot, requestedRoot)).catch(() => null);
|
|
34409
34530
|
if (candidate === null) return null;
|
|
34410
|
-
const relative =
|
|
34411
|
-
if (relative.startsWith(`..${
|
|
34531
|
+
const relative = path65.relative(projectRoot, candidate);
|
|
34532
|
+
if (relative.startsWith(`..${path65.sep}`) || relative === ".." || path65.isAbsolute(relative)) {
|
|
34412
34533
|
return null;
|
|
34413
34534
|
}
|
|
34414
34535
|
return {
|
|
34415
34536
|
root: candidate,
|
|
34416
|
-
scopeRoot: relative.split(
|
|
34537
|
+
scopeRoot: relative.split(path65.sep).join("/") || "."
|
|
34417
34538
|
};
|
|
34418
34539
|
}
|
|
34419
34540
|
|
|
34420
34541
|
// src/commands/status.ts
|
|
34421
34542
|
import { spawn } from "child_process";
|
|
34422
34543
|
import { promises as fs10 } from "fs";
|
|
34423
|
-
import
|
|
34544
|
+
import path66 from "path";
|
|
34424
34545
|
import process11 from "process";
|
|
34425
34546
|
|
|
34426
34547
|
// src/team/assessment.ts
|
|
@@ -34576,8 +34697,8 @@ var EXIT_OK9 = 0;
|
|
|
34576
34697
|
var EXIT_NOT_INITIALIZED6 = 1;
|
|
34577
34698
|
var EXIT_CORRUPT_STATE2 = 2;
|
|
34578
34699
|
async function status(rootDir = process11.cwd(), options = {}) {
|
|
34579
|
-
const stateFile =
|
|
34580
|
-
const v3SchemaFile =
|
|
34700
|
+
const stateFile = path66.join(rootDir, ".mancode", "state.json");
|
|
34701
|
+
const v3SchemaFile = path66.join(rootDir, ".mancode", "schema.json");
|
|
34581
34702
|
if (await pathExists13(v3SchemaFile)) {
|
|
34582
34703
|
return statusV3(rootDir, options);
|
|
34583
34704
|
}
|
|
@@ -34822,7 +34943,7 @@ async function readV3StatusSession(rootDir) {
|
|
|
34822
34943
|
}
|
|
34823
34944
|
async function shouldRefreshProject(rootDir, state) {
|
|
34824
34945
|
if (state.projectMode !== "generic") return false;
|
|
34825
|
-
const hasGit = await pathExists13(
|
|
34946
|
+
const hasGit = await pathExists13(path66.join(rootDir, ".git"));
|
|
34826
34947
|
if (hasGit) return true;
|
|
34827
34948
|
return hasProjectEvidence(rootDir);
|
|
34828
34949
|
}
|
|
@@ -34866,19 +34987,19 @@ async function getCurrentWorkflow(rootDir, taskId) {
|
|
|
34866
34987
|
}
|
|
34867
34988
|
async function getProjectName(rootDir) {
|
|
34868
34989
|
try {
|
|
34869
|
-
const raw = await fs10.readFile(
|
|
34990
|
+
const raw = await fs10.readFile(path66.join(rootDir, "package.json"), "utf-8");
|
|
34870
34991
|
const pkg = JSON.parse(raw);
|
|
34871
34992
|
if (pkg.name && typeof pkg.name === "string") {
|
|
34872
34993
|
return pkg.name;
|
|
34873
34994
|
}
|
|
34874
34995
|
} catch {
|
|
34875
34996
|
}
|
|
34876
|
-
return
|
|
34997
|
+
return path66.basename(rootDir);
|
|
34877
34998
|
}
|
|
34878
34999
|
async function readConfig3(rootDir) {
|
|
34879
35000
|
try {
|
|
34880
35001
|
const raw = await fs10.readFile(
|
|
34881
|
-
|
|
35002
|
+
path66.join(rootDir, ".mancode", "config.json"),
|
|
34882
35003
|
"utf-8"
|
|
34883
35004
|
);
|
|
34884
35005
|
return JSON.parse(raw);
|
|
@@ -34906,9 +35027,9 @@ function getEffectiveTeamStatus(state, config, detected) {
|
|
|
34906
35027
|
}
|
|
34907
35028
|
async function checkHooks(rootDir) {
|
|
34908
35029
|
const [sessionStart, userPromptSubmit, registered] = await Promise.all([
|
|
34909
|
-
pathExists13(
|
|
35030
|
+
pathExists13(path66.join(rootDir, ".mancode", "hooks", "session-start.mjs")),
|
|
34910
35031
|
pathExists13(
|
|
34911
|
-
|
|
35032
|
+
path66.join(rootDir, ".mancode", "hooks", "user-prompt-submit.mjs")
|
|
34912
35033
|
),
|
|
34913
35034
|
isRegistered(rootDir)
|
|
34914
35035
|
]);
|
|
@@ -34917,7 +35038,7 @@ async function checkHooks(rootDir) {
|
|
|
34917
35038
|
async function isRegistered(rootDir) {
|
|
34918
35039
|
try {
|
|
34919
35040
|
const raw = await fs10.readFile(
|
|
34920
|
-
|
|
35041
|
+
path66.join(rootDir, ".claude", "settings.json"),
|
|
34921
35042
|
"utf-8"
|
|
34922
35043
|
);
|
|
34923
35044
|
const settings = JSON.parse(raw);
|
|
@@ -34946,7 +35067,7 @@ function hasHookCommand2(value, needle) {
|
|
|
34946
35067
|
});
|
|
34947
35068
|
}
|
|
34948
35069
|
async function estimateHookInjection(rootDir) {
|
|
34949
|
-
const hookPath =
|
|
35070
|
+
const hookPath = path66.join(
|
|
34950
35071
|
rootDir,
|
|
34951
35072
|
".mancode",
|
|
34952
35073
|
"hooks",
|
|
@@ -36444,7 +36565,7 @@ function assertPositiveRevision2(value, label) {
|
|
|
36444
36565
|
|
|
36445
36566
|
// src/team/git-ref-handoff-repair.ts
|
|
36446
36567
|
import { lstat as lstat26, mkdir as mkdir35, readFile as readFile42, readdir as readdir18, writeFile as writeFile44 } from "fs/promises";
|
|
36447
|
-
import
|
|
36568
|
+
import path67 from "path";
|
|
36448
36569
|
|
|
36449
36570
|
// src/team/git-ref-operation.ts
|
|
36450
36571
|
import { execFile as execFileCallback5 } from "child_process";
|
|
@@ -39022,7 +39143,7 @@ async function recoverGitRefHandoffRepairs(projectRoot) {
|
|
|
39022
39143
|
}
|
|
39023
39144
|
async function recoverGitRefHandoffRepair(projectRoot, operationId, transportReceipt) {
|
|
39024
39145
|
assertUlid(operationId, "git-ref handoff repair operationId");
|
|
39025
|
-
const root =
|
|
39146
|
+
const root = path67.resolve(projectRoot);
|
|
39026
39147
|
let journal = await requireJournal2(root, operationId);
|
|
39027
39148
|
if (journal.state === "committed" || journal.state === "aborted") {
|
|
39028
39149
|
return recoveryResult2(journal);
|
|
@@ -39101,7 +39222,7 @@ async function recoverGitRefHandoffRepair(projectRoot, operationId, transportRec
|
|
|
39101
39222
|
}
|
|
39102
39223
|
}
|
|
39103
39224
|
async function prepareHandoffRepairWhileTaskLocked(projectRoot, rawPrepared) {
|
|
39104
|
-
const root =
|
|
39225
|
+
const root = path67.resolve(projectRoot);
|
|
39105
39226
|
const prepared2 = parsePrepared2(rawPrepared);
|
|
39106
39227
|
const runtime = await readProjectRuntimeContext(root);
|
|
39107
39228
|
const previousMetadata = bundleMetadata2(prepared2.predecessorBundle);
|
|
@@ -39164,7 +39285,7 @@ async function restorePredecessorMetadata2(projectRoot, journal) {
|
|
|
39164
39285
|
);
|
|
39165
39286
|
}
|
|
39166
39287
|
async function replaceMetadataVerified(projectRoot, expected, targetMetadata, alternateExpected) {
|
|
39167
|
-
const target =
|
|
39288
|
+
const target = path67.join(
|
|
39168
39289
|
taskRootPath(projectRoot, targetMetadata.taskRef),
|
|
39169
39290
|
"metadata.json"
|
|
39170
39291
|
);
|
|
@@ -39333,7 +39454,7 @@ async function listJournals2(projectRoot) {
|
|
|
39333
39454
|
parseJournal3(
|
|
39334
39455
|
JSON.parse(
|
|
39335
39456
|
await readFile42(
|
|
39336
|
-
|
|
39457
|
+
path67.join(journalDirectory2(projectRoot), entry),
|
|
39337
39458
|
"utf8"
|
|
39338
39459
|
)
|
|
39339
39460
|
)
|
|
@@ -39355,17 +39476,17 @@ async function readSafeFile2(target) {
|
|
|
39355
39476
|
return content;
|
|
39356
39477
|
}
|
|
39357
39478
|
async function atomicWrite2(target, content) {
|
|
39358
|
-
const temporary =
|
|
39359
|
-
|
|
39360
|
-
`.${
|
|
39479
|
+
const temporary = path67.join(
|
|
39480
|
+
path67.dirname(target),
|
|
39481
|
+
`.${path67.basename(target)}.${process.pid}.${Date.now()}.tmp`
|
|
39361
39482
|
);
|
|
39362
39483
|
await writeFile44(temporary, content, { encoding: "utf8", flag: "wx" });
|
|
39363
39484
|
await replaceFileAtomically(temporary, target);
|
|
39364
39485
|
}
|
|
39365
39486
|
async function ensureJournalDirectory2(projectRoot) {
|
|
39366
|
-
let current =
|
|
39487
|
+
let current = path67.resolve(projectRoot);
|
|
39367
39488
|
for (const segment of [".mancode", "local", "journals", "git-ref-handoff"]) {
|
|
39368
|
-
current =
|
|
39489
|
+
current = path67.join(current, segment);
|
|
39369
39490
|
try {
|
|
39370
39491
|
await mkdir35(current);
|
|
39371
39492
|
} catch (error) {
|
|
@@ -39378,8 +39499,8 @@ async function ensureJournalDirectory2(projectRoot) {
|
|
|
39378
39499
|
}
|
|
39379
39500
|
}
|
|
39380
39501
|
function journalDirectory2(projectRoot) {
|
|
39381
|
-
return
|
|
39382
|
-
|
|
39502
|
+
return path67.join(
|
|
39503
|
+
path67.resolve(projectRoot),
|
|
39383
39504
|
".mancode",
|
|
39384
39505
|
"local",
|
|
39385
39506
|
"journals",
|
|
@@ -39388,7 +39509,7 @@ function journalDirectory2(projectRoot) {
|
|
|
39388
39509
|
}
|
|
39389
39510
|
function journalPath3(projectRoot, operationId) {
|
|
39390
39511
|
assertUlid(operationId, "git-ref handoff repair operationId");
|
|
39391
|
-
return
|
|
39512
|
+
return path67.join(journalDirectory2(projectRoot), `${operationId}.json`);
|
|
39392
39513
|
}
|
|
39393
39514
|
function serialize11(value) {
|
|
39394
39515
|
return `${JSON.stringify(value, null, 2)}
|
|
@@ -39488,7 +39609,7 @@ function parseReceipt(value) {
|
|
|
39488
39609
|
|
|
39489
39610
|
// src/team/policy-operation.ts
|
|
39490
39611
|
import { lstat as lstat27, mkdir as mkdir36, readdir as readdir19, unlink as unlink3, writeFile as writeFile45 } from "fs/promises";
|
|
39491
|
-
import
|
|
39612
|
+
import path68 from "path";
|
|
39492
39613
|
async function updateTeamPolicy(input) {
|
|
39493
39614
|
const operationId = input.operationId ?? createUlid();
|
|
39494
39615
|
const eventId = createUlid();
|
|
@@ -39499,7 +39620,7 @@ async function updateTeamPolicy(input) {
|
|
|
39499
39620
|
throw new Error("MANCODE_TEAM_POLICY_INVALID");
|
|
39500
39621
|
}
|
|
39501
39622
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
39502
|
-
const root =
|
|
39623
|
+
const root = path68.resolve(input.projectRoot);
|
|
39503
39624
|
const runtime = await readProjectRuntimeContext(root);
|
|
39504
39625
|
const store = resolveCoordinationEntityHomeStore(
|
|
39505
39626
|
runtime.entityHomeStoreContext
|
|
@@ -39580,7 +39701,7 @@ async function applyTeamTransportSet(input, write) {
|
|
|
39580
39701
|
}
|
|
39581
39702
|
const remote = transportRemote(input.mode, input.remote);
|
|
39582
39703
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
39583
|
-
const root =
|
|
39704
|
+
const root = path68.resolve(input.projectRoot);
|
|
39584
39705
|
const runtime = await readProjectRuntimeContext(root);
|
|
39585
39706
|
const store = resolveCoordinationEntityHomeStore(
|
|
39586
39707
|
runtime.entityHomeStoreContext
|
|
@@ -39713,9 +39834,9 @@ async function assertTransportAuthorityEmpty(projectRoot, store) {
|
|
|
39713
39834
|
listClaims(store),
|
|
39714
39835
|
listHandoffs(store),
|
|
39715
39836
|
directoryHasEntries(taskHeadDirectory(store)),
|
|
39716
|
-
directoryHasEntries(
|
|
39837
|
+
directoryHasEntries(path68.join(store.root, "transport-migrations")),
|
|
39717
39838
|
directoryHasEntries(
|
|
39718
|
-
|
|
39839
|
+
path68.join(projectRoot, ".mancode", "shared", "team", "transport")
|
|
39719
39840
|
),
|
|
39720
39841
|
pathExists14(gitRefCachePath(projectRoot))
|
|
39721
39842
|
]);
|
|
@@ -39745,18 +39866,18 @@ function assertPositiveRevision5(value, label) {
|
|
|
39745
39866
|
}
|
|
39746
39867
|
}
|
|
39747
39868
|
function teamPolicyPath(projectRoot) {
|
|
39748
|
-
return
|
|
39869
|
+
return path68.join(projectRoot, ".mancode", "shared", "team", "policy.json");
|
|
39749
39870
|
}
|
|
39750
39871
|
function projectConfigPath(projectRoot) {
|
|
39751
|
-
return
|
|
39872
|
+
return path68.join(projectRoot, ".mancode", "shared", "config.json");
|
|
39752
39873
|
}
|
|
39753
39874
|
async function writeJsonAtomic4(target, value) {
|
|
39754
|
-
await mkdir36(
|
|
39755
|
-
await assertPlainDirectory(
|
|
39875
|
+
await mkdir36(path68.dirname(target), { recursive: true });
|
|
39876
|
+
await assertPlainDirectory(path68.dirname(target));
|
|
39756
39877
|
await assertPlainFileOrMissing(target);
|
|
39757
|
-
const temporary =
|
|
39758
|
-
|
|
39759
|
-
`.${
|
|
39878
|
+
const temporary = path68.join(
|
|
39879
|
+
path68.dirname(target),
|
|
39880
|
+
`.${path68.basename(target)}.${process.pid}.${createUlid()}.tmp`
|
|
39760
39881
|
);
|
|
39761
39882
|
try {
|
|
39762
39883
|
await writeFile45(temporary, `${JSON.stringify(value, null, 2)}
|
|
@@ -39825,7 +39946,7 @@ import {
|
|
|
39825
39946
|
unlink as unlink4,
|
|
39826
39947
|
writeFile as writeFile46
|
|
39827
39948
|
} from "fs/promises";
|
|
39828
|
-
import
|
|
39949
|
+
import path69 from "path";
|
|
39829
39950
|
|
|
39830
39951
|
// src/team/transport-migration.ts
|
|
39831
39952
|
var DIGEST_PATTERN5 = /^sha256:[a-f0-9]{64}$/;
|
|
@@ -40904,7 +41025,7 @@ function compareUtf812(left, right) {
|
|
|
40904
41025
|
var STAGE_DIRECTORY = "transport-migrations";
|
|
40905
41026
|
var COLLECTIONS = ["claims", "handoffs", "task-heads"];
|
|
40906
41027
|
async function createTransportMigrationFileAdapters(input) {
|
|
40907
|
-
const projectRoot =
|
|
41028
|
+
const projectRoot = path69.resolve(input.projectRoot);
|
|
40908
41029
|
assertUlid(input.actorId, "transport migration adapter actorId");
|
|
40909
41030
|
if (input.operationId !== void 0) {
|
|
40910
41031
|
assertUlid(input.operationId, "transport migration adapter operationId");
|
|
@@ -40972,7 +41093,7 @@ async function createTransportMigrationFileAdapters(input) {
|
|
|
40972
41093
|
var FileSystemTransportMigrationConfigAdapter = class {
|
|
40973
41094
|
constructor(projectRoot, coordinationStore) {
|
|
40974
41095
|
this.coordinationStore = coordinationStore;
|
|
40975
|
-
this.projectRoot =
|
|
41096
|
+
this.projectRoot = path69.resolve(projectRoot);
|
|
40976
41097
|
}
|
|
40977
41098
|
projectRoot;
|
|
40978
41099
|
async read() {
|
|
@@ -41838,7 +41959,7 @@ async function publishMigrationActorProfiles(projectRoot, profiles) {
|
|
|
41838
41959
|
}
|
|
41839
41960
|
}
|
|
41840
41961
|
async function archiveLocalCoordinationCollections(store, operationId) {
|
|
41841
|
-
const archiveRoot =
|
|
41962
|
+
const archiveRoot = path69.join(
|
|
41842
41963
|
store.root,
|
|
41843
41964
|
STAGE_DIRECTORY,
|
|
41844
41965
|
"archive",
|
|
@@ -41851,8 +41972,8 @@ async function archiveLocalCoordinationCollections(store, operationId) {
|
|
|
41851
41972
|
"task-heads": taskHeadDirectory(store)
|
|
41852
41973
|
};
|
|
41853
41974
|
for (const name of COLLECTIONS) {
|
|
41854
|
-
const archived =
|
|
41855
|
-
const absent =
|
|
41975
|
+
const archived = path69.join(archiveRoot, name);
|
|
41976
|
+
const absent = path69.join(archiveRoot, `${name}.absent`);
|
|
41856
41977
|
if (await pathKind(archived) === "directory" || await pathKind(absent) === "file") {
|
|
41857
41978
|
continue;
|
|
41858
41979
|
}
|
|
@@ -41890,7 +42011,7 @@ async function listActorProfiles(projectRoot) {
|
|
|
41890
42011
|
return profiles;
|
|
41891
42012
|
}
|
|
41892
42013
|
async function listSharedTaskRefs(projectRoot) {
|
|
41893
|
-
const directory =
|
|
42014
|
+
const directory = path69.join(projectRoot, ".mancode", "shared", "workflows");
|
|
41894
42015
|
let entries;
|
|
41895
42016
|
try {
|
|
41896
42017
|
entries = await readdir20(directory);
|
|
@@ -41901,7 +42022,7 @@ async function listSharedTaskRefs(projectRoot) {
|
|
|
41901
42022
|
const refs = [];
|
|
41902
42023
|
for (const taskId of entries.sort(compareUtf813)) {
|
|
41903
42024
|
assertUlid(taskId, "shared workflow directory");
|
|
41904
|
-
const stat5 = await lstat28(
|
|
42025
|
+
const stat5 = await lstat28(path69.join(directory, taskId));
|
|
41905
42026
|
if (!stat5.isDirectory() || stat5.isSymbolicLink()) {
|
|
41906
42027
|
throw new Error("MANCODE_CONTEXT_PATH_UNSAFE");
|
|
41907
42028
|
}
|
|
@@ -41975,7 +42096,7 @@ async function readStagedRecord(store, operationId) {
|
|
|
41975
42096
|
);
|
|
41976
42097
|
}
|
|
41977
42098
|
function stagedPath(store, operationId) {
|
|
41978
|
-
return
|
|
42099
|
+
return path69.join(
|
|
41979
42100
|
store.root,
|
|
41980
42101
|
STAGE_DIRECTORY,
|
|
41981
42102
|
"staged",
|
|
@@ -41983,7 +42104,7 @@ function stagedPath(store, operationId) {
|
|
|
41983
42104
|
);
|
|
41984
42105
|
}
|
|
41985
42106
|
function establishedPath(store, operationId) {
|
|
41986
|
-
return
|
|
42107
|
+
return path69.join(
|
|
41987
42108
|
store.root,
|
|
41988
42109
|
STAGE_DIRECTORY,
|
|
41989
42110
|
"established",
|
|
@@ -41991,7 +42112,7 @@ function establishedPath(store, operationId) {
|
|
|
41991
42112
|
);
|
|
41992
42113
|
}
|
|
41993
42114
|
function projectConfigPath2(projectRoot) {
|
|
41994
|
-
return
|
|
42115
|
+
return path69.join(projectRoot, ".mancode", "shared", "config.json");
|
|
41995
42116
|
}
|
|
41996
42117
|
async function readProjectConfigFile(projectRoot) {
|
|
41997
42118
|
try {
|
|
@@ -42006,11 +42127,11 @@ async function readProjectConfigFile(projectRoot) {
|
|
|
42006
42127
|
}
|
|
42007
42128
|
}
|
|
42008
42129
|
async function writeJsonAtomic5(target, value) {
|
|
42009
|
-
await mkdir37(
|
|
42010
|
-
await assertPlainDirectory2(
|
|
42011
|
-
const temporary =
|
|
42012
|
-
|
|
42013
|
-
`.${
|
|
42130
|
+
await mkdir37(path69.dirname(target), { recursive: true });
|
|
42131
|
+
await assertPlainDirectory2(path69.dirname(target));
|
|
42132
|
+
const temporary = path69.join(
|
|
42133
|
+
path69.dirname(target),
|
|
42134
|
+
`.${path69.basename(target)}.${process.pid}.${createUlid()}.tmp`
|
|
42014
42135
|
);
|
|
42015
42136
|
try {
|
|
42016
42137
|
await writeFile46(temporary, serialize12(value), {
|
|
@@ -42024,8 +42145,8 @@ async function writeJsonAtomic5(target, value) {
|
|
|
42024
42145
|
}
|
|
42025
42146
|
}
|
|
42026
42147
|
async function writeJsonExclusiveOrEqual(target, value, parser, conflictCode) {
|
|
42027
|
-
await mkdir37(
|
|
42028
|
-
await assertPlainDirectory2(
|
|
42148
|
+
await mkdir37(path69.dirname(target), { recursive: true });
|
|
42149
|
+
await assertPlainDirectory2(path69.dirname(target));
|
|
42029
42150
|
try {
|
|
42030
42151
|
await writeFile46(target, serialize12(value), { encoding: "utf8", flag: "wx" });
|
|
42031
42152
|
} catch (error) {
|
|
@@ -43576,15 +43697,15 @@ function parsePositiveInteger5(value) {
|
|
|
43576
43697
|
|
|
43577
43698
|
// src/commands/uninstall.ts
|
|
43578
43699
|
import { access as access5, readFile as readFile44, rm as rm22, writeFile as writeFile47 } from "fs/promises";
|
|
43579
|
-
import
|
|
43700
|
+
import path70 from "path";
|
|
43580
43701
|
import process12 from "process";
|
|
43581
43702
|
var EXIT_OK10 = 0;
|
|
43582
43703
|
var EXIT_NOT_INITIALIZED7 = 1;
|
|
43583
43704
|
var EXIT_UNSUPPORTED_PLATFORM2 = 2;
|
|
43584
43705
|
var EXIT_V3_AUTHORITY_PROTECTED = 3;
|
|
43585
43706
|
async function uninstall(rootDir = process12.cwd(), platform, options = {}) {
|
|
43586
|
-
const stateFile =
|
|
43587
|
-
const v3SchemaFile =
|
|
43707
|
+
const stateFile = path70.join(rootDir, ".mancode", "state.json");
|
|
43708
|
+
const v3SchemaFile = path70.join(rootDir, ".mancode", "schema.json");
|
|
43588
43709
|
if (await pathExists15(v3SchemaFile)) {
|
|
43589
43710
|
return uninstallV3(rootDir, platform, options);
|
|
43590
43711
|
}
|
|
@@ -43681,7 +43802,7 @@ async function uninstallAll(rootDir) {
|
|
|
43681
43802
|
await uninstallPlatform(rootDir, p);
|
|
43682
43803
|
}
|
|
43683
43804
|
console.log("\u2713 Removing .mancode/ directory...");
|
|
43684
|
-
await rm22(
|
|
43805
|
+
await rm22(path70.join(rootDir, ".mancode"), {
|
|
43685
43806
|
recursive: true,
|
|
43686
43807
|
force: true
|
|
43687
43808
|
});
|
|
@@ -43691,7 +43812,7 @@ async function uninstallClaudeCode(rootDir) {
|
|
|
43691
43812
|
await cleanClaudeSettings(rootDir);
|
|
43692
43813
|
}
|
|
43693
43814
|
async function cleanClaudeSettings(rootDir) {
|
|
43694
|
-
const settingsPath =
|
|
43815
|
+
const settingsPath = path70.join(rootDir, ".claude", "settings.json");
|
|
43695
43816
|
let content;
|
|
43696
43817
|
try {
|
|
43697
43818
|
content = await readFile44(settingsPath, "utf-8");
|
|
@@ -43769,7 +43890,7 @@ async function uninstallCursor(rootDir) {
|
|
|
43769
43890
|
await removeCursorCommands(rootDir);
|
|
43770
43891
|
}
|
|
43771
43892
|
async function uninstallCodex(rootDir) {
|
|
43772
|
-
const agentsPath =
|
|
43893
|
+
const agentsPath = path70.join(rootDir, "AGENTS.md");
|
|
43773
43894
|
try {
|
|
43774
43895
|
const content = await readFile44(agentsPath, "utf-8");
|
|
43775
43896
|
const cleaned = removeManagedBlock(content);
|
|
@@ -43784,7 +43905,7 @@ async function uninstallCodex(rootDir) {
|
|
|
43784
43905
|
await removeCodexSkills(rootDir);
|
|
43785
43906
|
}
|
|
43786
43907
|
async function uninstallCopilot(rootDir) {
|
|
43787
|
-
const instructionsPath =
|
|
43908
|
+
const instructionsPath = path70.join(
|
|
43788
43909
|
rootDir,
|
|
43789
43910
|
".github",
|
|
43790
43911
|
"copilot-instructions.md"
|
|
@@ -43803,7 +43924,7 @@ async function uninstallCopilot(rootDir) {
|
|
|
43803
43924
|
await removeCopilotPrompts(rootDir);
|
|
43804
43925
|
}
|
|
43805
43926
|
async function uninstallZcode(rootDir) {
|
|
43806
|
-
const agentsPath =
|
|
43927
|
+
const agentsPath = path70.join(rootDir, "AGENTS.md");
|
|
43807
43928
|
try {
|
|
43808
43929
|
const content = await readFile44(agentsPath, "utf-8");
|
|
43809
43930
|
const cleaned = removeManagedBlock(
|
|
@@ -43822,7 +43943,7 @@ async function uninstallZcode(rootDir) {
|
|
|
43822
43943
|
await removeZcodeSkills(rootDir);
|
|
43823
43944
|
}
|
|
43824
43945
|
async function uninstallKimiCode(rootDir) {
|
|
43825
|
-
const agentsPath =
|
|
43946
|
+
const agentsPath = path70.join(rootDir, "AGENTS.md");
|
|
43826
43947
|
try {
|
|
43827
43948
|
const content = await readFile44(agentsPath, "utf-8");
|
|
43828
43949
|
const cleaned = removeManagedBlock(
|
|
@@ -43841,7 +43962,7 @@ async function uninstallKimiCode(rootDir) {
|
|
|
43841
43962
|
await removeKimiSkills(rootDir);
|
|
43842
43963
|
}
|
|
43843
43964
|
async function uninstallQoder(rootDir) {
|
|
43844
|
-
const agentsPath =
|
|
43965
|
+
const agentsPath = path70.join(rootDir, "AGENTS.md");
|
|
43845
43966
|
try {
|
|
43846
43967
|
const content = await readFile44(agentsPath, "utf-8");
|
|
43847
43968
|
const cleaned = removeManagedBlock(
|
|
@@ -43861,7 +43982,7 @@ async function uninstallQoder(rootDir) {
|
|
|
43861
43982
|
}
|
|
43862
43983
|
async function uninstallDsh(rootDir) {
|
|
43863
43984
|
await assertDshAdapterPathsSafe(rootDir);
|
|
43864
|
-
const agentsPath =
|
|
43985
|
+
const agentsPath = path70.join(rootDir, "AGENTS.md");
|
|
43865
43986
|
try {
|
|
43866
43987
|
const content = await readFile44(agentsPath, "utf-8");
|
|
43867
43988
|
const cleaned = removeManagedBlock(
|
|
@@ -43881,7 +44002,7 @@ async function uninstallDsh(rootDir) {
|
|
|
43881
44002
|
await removeDshSkills(rootDir);
|
|
43882
44003
|
}
|
|
43883
44004
|
async function removeFromConfig(rootDir, platform) {
|
|
43884
|
-
const configPath =
|
|
44005
|
+
const configPath = path70.join(rootDir, ".mancode", "config.json");
|
|
43885
44006
|
try {
|
|
43886
44007
|
const raw = await readFile44(configPath, "utf-8");
|
|
43887
44008
|
const config = JSON.parse(raw);
|
|
@@ -43954,7 +44075,7 @@ var CONTINUITY_COMPATIBILITY_SUBCOMMANDS = /* @__PURE__ */ new Set(["clean"]);
|
|
|
43954
44075
|
|
|
43955
44076
|
// src/commands/workflow.ts
|
|
43956
44077
|
import { access as access6, readFile as readFile49, rm as rm26, writeFile as writeFile51 } from "fs/promises";
|
|
43957
|
-
import
|
|
44078
|
+
import path76 from "path";
|
|
43958
44079
|
|
|
43959
44080
|
// src/context/child-result-merge.ts
|
|
43960
44081
|
async function mergeV3ChildResult(input) {
|
|
@@ -44293,11 +44414,11 @@ import {
|
|
|
44293
44414
|
rm as rm24,
|
|
44294
44415
|
writeFile as writeFile49
|
|
44295
44416
|
} from "fs/promises";
|
|
44296
|
-
import
|
|
44417
|
+
import path73 from "path";
|
|
44297
44418
|
import { promisify as promisify8 } from "util";
|
|
44298
44419
|
|
|
44299
44420
|
// src/context/man-delivery-plan.ts
|
|
44300
|
-
import
|
|
44421
|
+
import path71 from "path";
|
|
44301
44422
|
var SOURCE_PREFIX = "<!-- mancode:delivery-plan ";
|
|
44302
44423
|
var MARKERS = [
|
|
44303
44424
|
"<!-- mancode:plan-baseline:start -->",
|
|
@@ -44367,7 +44488,7 @@ ${document.slice(parsed.recordEnd)}`;
|
|
|
44367
44488
|
return next;
|
|
44368
44489
|
}
|
|
44369
44490
|
function assertManPlanPath(file) {
|
|
44370
|
-
if (!file ||
|
|
44491
|
+
if (!file || path71.posix.isAbsolute(file) || /[\\\r\n\0<>:]/.test(file) || file.split("/").some((part) => !part || part === "." || part === "..") || /^(?:\.git|\.mancode|架构|项目接口)(?:\/|$)/.test(file) || !file.endsWith(".md") || !file.includes("/"))
|
|
44371
44492
|
throw new Error("MANCODE_MAN_PLAN_PATH_INVALID");
|
|
44372
44493
|
}
|
|
44373
44494
|
function parseSource(value) {
|
|
@@ -44399,7 +44520,7 @@ function parseManDeliveryPlan(plan) {
|
|
|
44399
44520
|
// src/context/man-progress.ts
|
|
44400
44521
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
44401
44522
|
import { lstat as lstat29, readFile as readFile45, realpath as realpath3, rm as rm23, writeFile as writeFile48 } from "fs/promises";
|
|
44402
|
-
import
|
|
44523
|
+
import path72 from "path";
|
|
44403
44524
|
var START = '<script type="application/json" id="mancode-progress-data">';
|
|
44404
44525
|
var END = "</script>";
|
|
44405
44526
|
function updateManProgressHtml(html, taskId, status2, reason) {
|
|
@@ -44431,7 +44552,7 @@ ${JSON.stringify(data).replaceAll("<", "\\u003c")}
|
|
|
44431
44552
|
${html.slice(end)}`;
|
|
44432
44553
|
}
|
|
44433
44554
|
async function syncManProgressPage(root, taskId, status2, reason, allowed) {
|
|
44434
|
-
const target =
|
|
44555
|
+
const target = path72.join(root, "\u9879\u76EE\u8FDB\u5EA6.html");
|
|
44435
44556
|
let temporary;
|
|
44436
44557
|
try {
|
|
44437
44558
|
const stat5 = await lstat29(target);
|
|
@@ -44440,7 +44561,7 @@ async function syncManProgressPage(root, taskId, status2, reason, allowed) {
|
|
|
44440
44561
|
status: "manual_sync",
|
|
44441
44562
|
reason: "progress page is outside the approved write scope"
|
|
44442
44563
|
};
|
|
44443
|
-
if (!stat5.isFile() || await realpath3(target) !==
|
|
44564
|
+
if (!stat5.isFile() || await realpath3(target) !== path72.join(await realpath3(root), "\u9879\u76EE\u8FDB\u5EA6.html"))
|
|
44444
44565
|
return {
|
|
44445
44566
|
status: "manual_sync",
|
|
44446
44567
|
reason: "progress page must be a regular project file"
|
|
@@ -44471,7 +44592,7 @@ async function syncManProgressPage(root, taskId, status2, reason, allowed) {
|
|
|
44471
44592
|
var execFile9 = promisify8(execFileCallback6);
|
|
44472
44593
|
var MAN_DELIVERY_POLICY = 3;
|
|
44473
44594
|
function isManDelivery(metadata) {
|
|
44474
|
-
return metadata.workflowMode === "man" && metadata.governance.policyVersions.planning === MAN_DELIVERY_POLICY
|
|
44595
|
+
return metadata.workflowMode === "man" && metadata.governance.policyVersions.planning === MAN_DELIVERY_POLICY;
|
|
44475
44596
|
}
|
|
44476
44597
|
async function manGit(root, args) {
|
|
44477
44598
|
return (await execFile9("git", args, {
|
|
@@ -44494,8 +44615,8 @@ async function hasGitWorktree(root) {
|
|
|
44494
44615
|
async function readManPlanFile(root, file) {
|
|
44495
44616
|
assertManPlanPath(file);
|
|
44496
44617
|
const resolvedRoot = await realpath4(root);
|
|
44497
|
-
const resolved = await realpath4(
|
|
44498
|
-
const relative =
|
|
44618
|
+
const resolved = await realpath4(path73.join(root, file));
|
|
44619
|
+
const relative = path73.relative(resolvedRoot, resolved).split(path73.sep).join("/");
|
|
44499
44620
|
assertManPlanPath(relative);
|
|
44500
44621
|
if (relative !== file) throw new Error("MANCODE_MAN_PLAN_USE_REAL_PATH");
|
|
44501
44622
|
if (!(await lstat30(resolved)).isFile())
|
|
@@ -44551,7 +44672,7 @@ async function captureManSubject(root, task) {
|
|
|
44551
44672
|
const hashes = [];
|
|
44552
44673
|
for (const file of files) {
|
|
44553
44674
|
if (file.startsWith(".mancode/") || file === "\u9879\u76EE\u8FDB\u5EA6.html") continue;
|
|
44554
|
-
const absolute =
|
|
44675
|
+
const absolute = path73.join(root, file);
|
|
44555
44676
|
let contents;
|
|
44556
44677
|
let kind = "deleted";
|
|
44557
44678
|
try {
|
|
@@ -44559,11 +44680,11 @@ async function captureManSubject(root, task) {
|
|
|
44559
44680
|
kind = `file:${stat5.mode & 73}`;
|
|
44560
44681
|
if (stat5.isSymbolicLink()) {
|
|
44561
44682
|
kind = "symlink";
|
|
44562
|
-
const target =
|
|
44683
|
+
const target = path73.relative(
|
|
44563
44684
|
await realpath4(root),
|
|
44564
44685
|
await realpath4(absolute)
|
|
44565
44686
|
);
|
|
44566
|
-
if (target.startsWith(`..${
|
|
44687
|
+
if (target.startsWith(`..${path73.sep}`) || path73.isAbsolute(target))
|
|
44567
44688
|
throw new Error("MANCODE_MAN_EXTERNAL_DEPENDENCY_UNVERIFIED");
|
|
44568
44689
|
contents = `${await readlink3(absolute)}\0${await readFile46(absolute, "base64")}`;
|
|
44569
44690
|
} else if (stat5.isFile()) {
|
|
@@ -44634,9 +44755,9 @@ function assertManVerificationSubjects(task, verification, subject) {
|
|
|
44634
44755
|
}
|
|
44635
44756
|
function manScopeContains(metadata, file) {
|
|
44636
44757
|
return metadata.implementationScope.include.some(
|
|
44637
|
-
(include) =>
|
|
44758
|
+
(include) => path73.matchesGlob(file, include)
|
|
44638
44759
|
) && !metadata.implementationScope.exclude.some(
|
|
44639
|
-
(exclude) =>
|
|
44760
|
+
(exclude) => path73.matchesGlob(file, exclude)
|
|
44640
44761
|
);
|
|
44641
44762
|
}
|
|
44642
44763
|
function assertManPlanInScope(metadata, file) {
|
|
@@ -44647,7 +44768,7 @@ function assertManPlanInScope(metadata, file) {
|
|
|
44647
44768
|
}
|
|
44648
44769
|
function manDeliveryFinalization(task, subject, recordCurrent, outsideScope, outsideScopeDirty, pendingCommit) {
|
|
44649
44770
|
const blockers = [];
|
|
44650
|
-
if (task.metadata.governance.planDecision !== "governed_execution")
|
|
44771
|
+
if (task.metadata.governance.planDecision !== "governed_execution" && !isActiveSoloHandoff(task.metadata) && !(task.metadata.governance.planDecision === "solo_handoff" && task.metadata.status === "completed" && task.metadata.soloExecution?.state === "completed" && task.metadata.soloExecution.planVersion === task.metadata.governance.planVersion))
|
|
44651
44772
|
blockers.push({
|
|
44652
44773
|
code: "plan_execution_required",
|
|
44653
44774
|
status: task.metadata.governance.planDecision ?? "unconfirmed",
|
|
@@ -44658,7 +44779,9 @@ function manDeliveryFinalization(task, subject, recordCurrent, outsideScope, out
|
|
|
44658
44779
|
blockers.push({
|
|
44659
44780
|
code: "review_incomplete",
|
|
44660
44781
|
status: task.review.status === "passed" ? "stale" : task.review.status,
|
|
44661
|
-
nextAction: task.review.status === "blocked" ? "Fix the recorded findings, verify the changed module, and submit the targeted review result." :
|
|
44782
|
+
nextAction: task.review.status === "blocked" ? task.review.blockers.some((finding) => finding.status === "open") ? "Fix the recorded findings, verify the changed module, and submit the targeted review result." : task.review.delivery?.coverage.some(
|
|
44783
|
+
(criterion) => criterion.status === "missing"
|
|
44784
|
+
) ? "Complete the missing accepted behavior within the approved scope, verify it, and update the module review." : "Record the missing acceptance evidence when verification is available, then update the module review." : "Complete one module review for the current subject and apply its review ledger."
|
|
44662
44785
|
});
|
|
44663
44786
|
const verification = assessManVerification(task, subject);
|
|
44664
44787
|
if (verification.status !== "passed")
|
|
@@ -44926,7 +45049,7 @@ function renderManDeliveryRecord(task, subject) {
|
|
|
44926
45049
|
}
|
|
44927
45050
|
async function syncManDeliveryRecord(root, task) {
|
|
44928
45051
|
const bound = await readBoundManPlan(root, task);
|
|
44929
|
-
if (task.metadata.governance.planDecision === "governed_execution" && !manScopeContains(task.metadata, bound.source.path))
|
|
45052
|
+
if ((task.metadata.governance.planDecision === "governed_execution" || isActiveSoloHandoff(task.metadata)) && !manScopeContains(task.metadata, bound.source.path))
|
|
44930
45053
|
assertManPlanInScope(task.metadata, bound.source.path);
|
|
44931
45054
|
const subject = await hasGitWorktree(root) ? await captureManSubject(root, task) : void 0;
|
|
44932
45055
|
const next = replaceManDeliveryRecord(
|
|
@@ -44941,7 +45064,7 @@ async function syncManDeliveryRecord(root, task) {
|
|
|
44941
45064
|
throw new Error(
|
|
44942
45065
|
"MANCODE_MAN_DOCUMENT_SENSITIVE: redact credential-like text before versioning"
|
|
44943
45066
|
);
|
|
44944
|
-
const target = await realpath4(
|
|
45067
|
+
const target = await realpath4(path73.join(root, bound.source.path));
|
|
44945
45068
|
if (next !== bound.document) {
|
|
44946
45069
|
const temporary = `${target}.${randomUUID5()}.tmp`;
|
|
44947
45070
|
try {
|
|
@@ -44971,7 +45094,7 @@ async function syncManDeliveryRecord(root, task) {
|
|
|
44971
45094
|
const reason = task.metadata.status === "blocked" && unresolved.length ? unresolved.map((item) => item.statement).join("; ") : null;
|
|
44972
45095
|
const verified = subject !== void 0 && assessManVerification(task, subject).status === "passed";
|
|
44973
45096
|
const reviewed = task.review.status === "skipped" || task.review.status === "passed" && task.review.delivery?.subject.contentDigest === subject?.contentDigest && task.review.delivery?.subject.environment === subject?.environment;
|
|
44974
|
-
const status2 = reason ? "\u963B\u585E" : verified && reviewed ? "\u5DF2\u5B8C\u6210" : verified && task.review.status !== "blocked" ? "\u5F85\u5BA1\u6838" : task.metadata.currentStep >= 5 ? "\u8FDB\u884C\u4E2D" : "\u672A\u5B8C\u6210";
|
|
45097
|
+
const status2 = reason ? "\u963B\u585E" : verified && reviewed ? "\u5DF2\u5B8C\u6210" : verified && task.review.status !== "blocked" ? "\u5F85\u5BA1\u6838" : task.metadata.currentStep >= 5 || isActiveSoloHandoff(task.metadata) ? "\u8FDB\u884C\u4E2D" : "\u672A\u5B8C\u6210";
|
|
44975
45098
|
return syncManProgressPage(
|
|
44976
45099
|
root,
|
|
44977
45100
|
taskId,
|
|
@@ -45700,13 +45823,19 @@ async function reviseV3Plan(input) {
|
|
|
45700
45823
|
planDecisionSupplied: input.planDecision !== void 0,
|
|
45701
45824
|
sessionActorId: context.session.actorId
|
|
45702
45825
|
});
|
|
45826
|
+
const implementationScope = submittedScope ?? context.task.metadata.implementationScope;
|
|
45827
|
+
const scopeChanged = submittedScope !== null && submittedScope.digest !== context.task.metadata.implementationScope.digest;
|
|
45828
|
+
const executionResumption = assertPlanOnlyExecutionResumption({
|
|
45829
|
+
metadata: context.task.metadata,
|
|
45830
|
+
planDecision,
|
|
45831
|
+
authorityChanged: planChanged || scopeChanged,
|
|
45832
|
+
sessionActorId: context.session.actorId
|
|
45833
|
+
});
|
|
45703
45834
|
assertPlanRevisionEligible(
|
|
45704
45835
|
context.task.metadata,
|
|
45705
45836
|
context.task.requirements,
|
|
45706
|
-
executionScopeBinding
|
|
45837
|
+
executionScopeBinding || executionResumption
|
|
45707
45838
|
);
|
|
45708
|
-
const implementationScope = submittedScope ?? context.task.metadata.implementationScope;
|
|
45709
|
-
const scopeChanged = submittedScope !== null && submittedScope.digest !== context.task.metadata.implementationScope.digest;
|
|
45710
45839
|
if (planDecision === "governed_execution") {
|
|
45711
45840
|
assertExecutableImplementationScope(implementationScope);
|
|
45712
45841
|
if (isManDelivery(context.task.metadata)) {
|
|
@@ -45766,10 +45895,10 @@ async function reviseV3Plan(input) {
|
|
|
45766
45895
|
latestCheckpoint: context.task.latestCheckpoint
|
|
45767
45896
|
});
|
|
45768
45897
|
const taskHeadFence = nextTaskHeadFence(context, aggregate, timestamp4);
|
|
45769
|
-
if (planDecision === "plan_only") {
|
|
45898
|
+
if (planDecision === "plan_only" || executionResumption) {
|
|
45770
45899
|
await enqueueSessionPointerProjection(context.projectRoot, {
|
|
45771
45900
|
operationId: context.operationId,
|
|
45772
|
-
action: "clear",
|
|
45901
|
+
action: executionResumption ? "resume" : "clear",
|
|
45773
45902
|
sessionId: context.session.sessionId,
|
|
45774
45903
|
expectedPreviousTaskRef: context.session.activeTaskRef,
|
|
45775
45904
|
taskRef,
|
|
@@ -45885,7 +46014,7 @@ async function reviseV3Plan(input) {
|
|
|
45885
46014
|
await replaceTaskHeadFence(context.homeStore, taskHeadFence);
|
|
45886
46015
|
}
|
|
45887
46016
|
const operation = await commitTaskOperation(context, journal);
|
|
45888
|
-
if (planDecision === "plan_only") {
|
|
46017
|
+
if (planDecision === "plan_only" || executionResumption) {
|
|
45889
46018
|
try {
|
|
45890
46019
|
await reconcileProjectionIntents(
|
|
45891
46020
|
context.projectRoot,
|
|
@@ -45929,8 +46058,8 @@ function parsePlanDecision(value) {
|
|
|
45929
46058
|
}
|
|
45930
46059
|
return value;
|
|
45931
46060
|
}
|
|
45932
|
-
function assertPlanRevisionEligible(metadata, requirements,
|
|
45933
|
-
if (
|
|
46061
|
+
function assertPlanRevisionEligible(metadata, requirements, approvedAuthorityPreserved) {
|
|
46062
|
+
if (approvedAuthorityPreserved) {
|
|
45934
46063
|
assertReadyPlanRequirements(metadata, requirements);
|
|
45935
46064
|
return;
|
|
45936
46065
|
}
|
|
@@ -45948,6 +46077,25 @@ function assertPlanRevisionEligible(metadata, requirements, executionScopeBindin
|
|
|
45948
46077
|
}
|
|
45949
46078
|
assertReadyPlanRequirements(metadata, requirements);
|
|
45950
46079
|
}
|
|
46080
|
+
function assertPlanOnlyExecutionResumption(input) {
|
|
46081
|
+
const { metadata } = input;
|
|
46082
|
+
if (metadata.governance.planDecision !== "plan_only" || input.planDecision !== "governed_execution") {
|
|
46083
|
+
return false;
|
|
46084
|
+
}
|
|
46085
|
+
if (metadata.workflowMode !== "man" || metadata.taskRef.namespace !== "local" || metadata.coordination !== "single") {
|
|
46086
|
+
throw new Error("MANCODE_PLAN_RESUME_LOCAL_MAN_ONLY");
|
|
46087
|
+
}
|
|
46088
|
+
if (!["planned", "in_progress"].includes(metadata.status) || metadata.currentStep !== 4 || metadata.governance.planVersion < 1 || metadata.soloExecution !== null) {
|
|
46089
|
+
throw new Error("MANCODE_PLAN_RESUME_NOT_ELIGIBLE");
|
|
46090
|
+
}
|
|
46091
|
+
if (metadata.ownerActorId !== input.sessionActorId) {
|
|
46092
|
+
throw new Error("MANCODE_TASK_OWNER_REQUIRED");
|
|
46093
|
+
}
|
|
46094
|
+
if (input.authorityChanged) {
|
|
46095
|
+
throw new Error("MANCODE_PLAN_RESUME_AUTHORITY_CHANGED");
|
|
46096
|
+
}
|
|
46097
|
+
return true;
|
|
46098
|
+
}
|
|
45951
46099
|
function assertReadyPlanRequirements(metadata, requirements) {
|
|
45952
46100
|
if (metadata.governance.requirementsStatus !== "ready" || metadata.governance.requirementsDigest !== requirements.contentDigest || requirements.status !== "confirmed" || !requirementsAreReady(requirements)) {
|
|
45953
46101
|
throw new Error("MANCODE_PLAN_REQUIREMENTS_OR_DECISION_INVALID");
|
|
@@ -46833,6 +46981,7 @@ async function applyV3ReviewLedger(input) {
|
|
|
46833
46981
|
});
|
|
46834
46982
|
let journal = null;
|
|
46835
46983
|
try {
|
|
46984
|
+
assertSoloHandoffSession(context.task.metadata, context.session);
|
|
46836
46985
|
const subject = isManDelivery(context.task.metadata) ? await captureManSubject(input.projectRoot, context.task) : null;
|
|
46837
46986
|
assertManReviewCoverage(
|
|
46838
46987
|
context.task,
|
|
@@ -47002,6 +47151,7 @@ async function applyV3ReviewLedger(input) {
|
|
|
47002
47151
|
}
|
|
47003
47152
|
}
|
|
47004
47153
|
function assertReviewEligible(metadata, hasPlan) {
|
|
47154
|
+
if (isActiveSoloHandoff(metadata) && hasPlan) return;
|
|
47005
47155
|
if (metadata.workflowMode !== "man" && metadata.workflowMode !== "manteam") {
|
|
47006
47156
|
throw new Error("MANCODE_REVIEW_WORKFLOW_MODE_INVALID");
|
|
47007
47157
|
}
|
|
@@ -47202,6 +47352,7 @@ async function completeV3SoloHandoff(input) {
|
|
|
47202
47352
|
let journal = null;
|
|
47203
47353
|
try {
|
|
47204
47354
|
assertSoloCompletionEligible(context);
|
|
47355
|
+
await assertManDeliveryReady(input.projectRoot, context.task);
|
|
47205
47356
|
const timestamp4 = context.now.toISOString();
|
|
47206
47357
|
const completionGateMetadata = completedSoloAssignmentMetadata(
|
|
47207
47358
|
context.task.metadata,
|
|
@@ -47452,6 +47603,9 @@ async function completeV3Task(input) {
|
|
|
47452
47603
|
let journal = null;
|
|
47453
47604
|
try {
|
|
47454
47605
|
assertCompletionOutcome(context.task.metadata, input.outcome);
|
|
47606
|
+
if (context.task.metadata.workflowMode === "manba" && context.task.metadata.ownerActorId !== context.session.actorId) {
|
|
47607
|
+
throw new Error("MANCODE_TASK_OWNER_REQUIRED");
|
|
47608
|
+
}
|
|
47455
47609
|
if (taskRef.namespace === "shared" && context.project.config.transport.mode !== "local") {
|
|
47456
47610
|
throw new Error("MANCODE_GIT_REF_TRANSPORT_NOT_IMPLEMENTED");
|
|
47457
47611
|
}
|
|
@@ -47470,7 +47624,8 @@ async function completeV3Task(input) {
|
|
|
47470
47624
|
activeChildTaskRefs: activeChildren,
|
|
47471
47625
|
hasPendingRepairOperation: false,
|
|
47472
47626
|
activeClaimCount: activeClaims2.length,
|
|
47473
|
-
claimsWillReleaseOrTransfer: activeClaims2.length > 0
|
|
47627
|
+
claimsWillReleaseOrTransfer: activeClaims2.length > 0,
|
|
47628
|
+
diagnosticOutcome: input.outcome
|
|
47474
47629
|
}
|
|
47475
47630
|
);
|
|
47476
47631
|
const timestamp4 = context.now.toISOString();
|
|
@@ -47778,6 +47933,7 @@ async function recordV3Verification(input) {
|
|
|
47778
47933
|
});
|
|
47779
47934
|
let journal = null;
|
|
47780
47935
|
try {
|
|
47936
|
+
assertSoloHandoffSession(context.task.metadata, context.session);
|
|
47781
47937
|
const subject = isManDelivery(context.task.metadata) ? await captureManSubject(input.projectRoot, context.task) : null;
|
|
47782
47938
|
assertManVerificationSubjects(
|
|
47783
47939
|
context.task,
|
|
@@ -47903,6 +48059,7 @@ async function recordV3Verification(input) {
|
|
|
47903
48059
|
}
|
|
47904
48060
|
}
|
|
47905
48061
|
function assertVerificationEligible(metadata, hasPlan) {
|
|
48062
|
+
if (isActiveSoloHandoff(metadata) && hasPlan) return;
|
|
47906
48063
|
if (metadata.status !== "in_progress" && metadata.status !== "blocked") {
|
|
47907
48064
|
throw new Error("MANCODE_VERIFICATION_WORKFLOW_NOT_ACTIVE");
|
|
47908
48065
|
}
|
|
@@ -47965,7 +48122,7 @@ import {
|
|
|
47965
48122
|
rm as rm25,
|
|
47966
48123
|
writeFile as writeFile50
|
|
47967
48124
|
} from "fs/promises";
|
|
47968
|
-
import
|
|
48125
|
+
import path74 from "path";
|
|
47969
48126
|
|
|
47970
48127
|
// src/context/creation-resolution.ts
|
|
47971
48128
|
function resolveWorkflowCreation(request) {
|
|
@@ -48075,7 +48232,7 @@ function rejectConflict(provided, expected, label) {
|
|
|
48075
48232
|
|
|
48076
48233
|
// src/context/workflow-create.ts
|
|
48077
48234
|
async function createV3Workflow(input) {
|
|
48078
|
-
const projectRoot =
|
|
48235
|
+
const projectRoot = path74.resolve(requireProjectRoot2(input.projectRoot));
|
|
48079
48236
|
const task = requireText2(input.task, "workflow task");
|
|
48080
48237
|
const client = requireText2(input.client, "workflow client");
|
|
48081
48238
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
@@ -48263,8 +48420,8 @@ async function createV3Workflow(input) {
|
|
|
48263
48420
|
throw new Error("MANCODE_REVISION_CONFLICT");
|
|
48264
48421
|
}
|
|
48265
48422
|
const taskParent = await ensureSafeTaskParent3(projectRoot, taskRef);
|
|
48266
|
-
const targetDirectory =
|
|
48267
|
-
stagingDirectory =
|
|
48423
|
+
const targetDirectory = path74.join(taskParent, taskRef.taskId);
|
|
48424
|
+
stagingDirectory = path74.join(
|
|
48268
48425
|
taskParent,
|
|
48269
48426
|
`.${taskRef.taskId}.${operationId}.staging`
|
|
48270
48427
|
);
|
|
@@ -48726,7 +48883,7 @@ async function ensureSafeTaskParent3(projectRoot, taskRef) {
|
|
|
48726
48883
|
const segments = [".mancode", taskRef.namespace, "workflows"];
|
|
48727
48884
|
let current = projectRoot;
|
|
48728
48885
|
for (const segment of segments) {
|
|
48729
|
-
current =
|
|
48886
|
+
current = path74.join(current, segment);
|
|
48730
48887
|
const existing = await lstatOrNull5(current);
|
|
48731
48888
|
if (existing === null) {
|
|
48732
48889
|
await mkdir38(current);
|
|
@@ -48762,7 +48919,7 @@ async function writeStagedEntities(stagingDirectory, entities) {
|
|
|
48762
48919
|
}
|
|
48763
48920
|
async function writeStagedJson(stagingDirectory, fileName, value) {
|
|
48764
48921
|
await assertDirectory(stagingDirectory);
|
|
48765
|
-
const target =
|
|
48922
|
+
const target = path74.join(stagingDirectory, fileName);
|
|
48766
48923
|
await writeFile50(target, `${JSON.stringify(value, null, 2)}
|
|
48767
48924
|
`, {
|
|
48768
48925
|
encoding: "utf8",
|
|
@@ -48800,7 +48957,7 @@ async function validateStagedEntities(stagingDirectory) {
|
|
|
48800
48957
|
});
|
|
48801
48958
|
}
|
|
48802
48959
|
async function readStagedJson(stagingDirectory, fileName, parser) {
|
|
48803
|
-
const target =
|
|
48960
|
+
const target = path74.join(stagingDirectory, fileName);
|
|
48804
48961
|
const before = await lstat31(target);
|
|
48805
48962
|
if (!before.isFile() || before.isSymbolicLink()) {
|
|
48806
48963
|
throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
|
|
@@ -49257,7 +49414,8 @@ async function completeGitRefTask(input) {
|
|
|
49257
49414
|
activeChildTaskRefs: activeChildren,
|
|
49258
49415
|
hasPendingRepairOperation: false,
|
|
49259
49416
|
activeClaimCount: activeClaims2.length,
|
|
49260
|
-
claimsWillReleaseOrTransfer: activeClaims2.length > 0
|
|
49417
|
+
claimsWillReleaseOrTransfer: activeClaims2.length > 0,
|
|
49418
|
+
diagnosticOutcome: input.outcome
|
|
49261
49419
|
}
|
|
49262
49420
|
);
|
|
49263
49421
|
const timestamp4 = now.toISOString();
|
|
@@ -49856,7 +50014,7 @@ function compareUtf816(left, right) {
|
|
|
49856
50014
|
// src/commands/man-delivery.ts
|
|
49857
50015
|
import { execFile as execFileCallback7 } from "child_process";
|
|
49858
50016
|
import { readFile as readFile48 } from "fs/promises";
|
|
49859
|
-
import
|
|
50017
|
+
import path75 from "path";
|
|
49860
50018
|
import { promisify as promisify9 } from "util";
|
|
49861
50019
|
var execFile10 = promisify9(execFileCallback7);
|
|
49862
50020
|
async function manDeliveryCommand(root, args, options) {
|
|
@@ -49895,7 +50053,14 @@ async function manDeliveryCommand(root, args, options) {
|
|
|
49895
50053
|
if (action === "check") {
|
|
49896
50054
|
await assertManDeliveryReady(project.projectRoot, task);
|
|
49897
50055
|
assertTaskCompletionGate(
|
|
49898
|
-
{
|
|
50056
|
+
{
|
|
50057
|
+
...task,
|
|
50058
|
+
metadata: isActiveSoloHandoff(task.metadata) ? completedSoloAssignmentMetadata(
|
|
50059
|
+
task.metadata,
|
|
50060
|
+
(/* @__PURE__ */ new Date()).toISOString()
|
|
50061
|
+
) : task.metadata,
|
|
50062
|
+
planDigest: task.plan?.digest ?? null
|
|
50063
|
+
},
|
|
49899
50064
|
{
|
|
49900
50065
|
activeChildTaskRefs: await project.store.listActiveChildTaskRefs(taskRef),
|
|
49901
50066
|
hasPendingRepairOperation: false,
|
|
@@ -49922,6 +50087,7 @@ async function manDeliveryCommand(root, args, options) {
|
|
|
49922
50087
|
const actorId = context.session.actorId;
|
|
49923
50088
|
try {
|
|
49924
50089
|
task = context.task;
|
|
50090
|
+
assertSoloHandoffSession(task.metadata, context.session);
|
|
49925
50091
|
if (action === "sync") {
|
|
49926
50092
|
const progress = await syncManDeliveryRecord(project.projectRoot, task);
|
|
49927
50093
|
const synced = await project.store.readTaskSnapshot(taskRef);
|
|
@@ -49936,7 +50102,7 @@ async function manDeliveryCommand(root, args, options) {
|
|
|
49936
50102
|
finalization: finalization2
|
|
49937
50103
|
});
|
|
49938
50104
|
}
|
|
49939
|
-
if (task.metadata.governance.planDecision !== "governed_execution" || task.metadata.currentStep < 5 || task.metadata.status !== "in_progress") {
|
|
50105
|
+
if (!isActiveSoloHandoff(task.metadata) && (task.metadata.governance.planDecision !== "governed_execution" || task.metadata.currentStep < 5 || task.metadata.status !== "in_progress")) {
|
|
49940
50106
|
throw new Error("MANCODE_MAN_DELIVERY_EXECUTION_REQUIRED");
|
|
49941
50107
|
}
|
|
49942
50108
|
} finally {
|
|
@@ -49944,7 +50110,7 @@ async function manDeliveryCommand(root, args, options) {
|
|
|
49944
50110
|
}
|
|
49945
50111
|
if (!options.file) throw new Error("MANCODE_MAN_DELIVERY_INPUT_REQUIRED");
|
|
49946
50112
|
const input = JSON.parse(
|
|
49947
|
-
await readFile48(
|
|
50113
|
+
await readFile48(path75.resolve(project.projectRoot, options.file), "utf8")
|
|
49948
50114
|
);
|
|
49949
50115
|
let output;
|
|
49950
50116
|
if (action === "verify" || action === "confirm") {
|
|
@@ -50298,7 +50464,7 @@ async function workflow(rootDir, subcommand, args = [], options = {}) {
|
|
|
50298
50464
|
"Man delivery requires Continuity; legacy workflows are unchanged."
|
|
50299
50465
|
);
|
|
50300
50466
|
}
|
|
50301
|
-
if (!await pathExists16(
|
|
50467
|
+
if (!await pathExists16(path76.join(rootDir, ".mancode", "state.json"))) {
|
|
50302
50468
|
if (v3Activation !== null) {
|
|
50303
50469
|
return printV3Error(
|
|
50304
50470
|
options.json,
|
|
@@ -51383,7 +51549,7 @@ function parseV3ParticipantActorIds(values) {
|
|
|
51383
51549
|
return values;
|
|
51384
51550
|
}
|
|
51385
51551
|
async function readWorkflowInputFile(projectRoot, value) {
|
|
51386
|
-
const inputPath =
|
|
51552
|
+
const inputPath = path76.isAbsolute(value) ? value : path76.resolve(projectRoot, value);
|
|
51387
51553
|
return readFile49(inputPath, "utf8");
|
|
51388
51554
|
}
|
|
51389
51555
|
async function readWorkflowJsonInputFile(projectRoot, value) {
|
|
@@ -51458,7 +51624,7 @@ async function readV3ActivationState2(rootDir) {
|
|
|
51458
51624
|
try {
|
|
51459
51625
|
const manifest = parseSchemaManifest(
|
|
51460
51626
|
JSON.parse(
|
|
51461
|
-
await readFile49(
|
|
51627
|
+
await readFile49(path76.join(rootDir, ".mancode", "schema.json"), "utf8")
|
|
51462
51628
|
)
|
|
51463
51629
|
);
|
|
51464
51630
|
return manifest.activationState === "v3_active" ? "v3_active" : "other";
|
|
@@ -51503,15 +51669,15 @@ async function workflowRequirements(rootDir, args, options) {
|
|
|
51503
51669
|
"requirements can only be finalized for an in-progress man or manteam workflow at step 1 or 2"
|
|
51504
51670
|
);
|
|
51505
51671
|
}
|
|
51506
|
-
const workflowPath =
|
|
51507
|
-
const jsonPath =
|
|
51508
|
-
const markdownPath =
|
|
51509
|
-
const metadataPath3 =
|
|
51672
|
+
const workflowPath = path76.join(rootDir, ".mancode", "workflows", taskId);
|
|
51673
|
+
const jsonPath = path76.join(workflowPath, "requirements.json");
|
|
51674
|
+
const markdownPath = path76.join(workflowPath, "requirements.md");
|
|
51675
|
+
const metadataPath3 = path76.join(workflowPath, "metadata.json");
|
|
51510
51676
|
let originalJson;
|
|
51511
51677
|
let originalMarkdown;
|
|
51512
51678
|
let originalMetadata;
|
|
51513
51679
|
try {
|
|
51514
|
-
const inputPath =
|
|
51680
|
+
const inputPath = path76.isAbsolute(options.file) ? options.file : path76.resolve(rootDir, options.file);
|
|
51515
51681
|
const input = await readFile49(inputPath, "utf-8");
|
|
51516
51682
|
const requirements = parseRequirementsLedger2(input);
|
|
51517
51683
|
assertRequirementsScopeConsistent2(requirements);
|
|
@@ -51636,7 +51802,7 @@ async function workflowVerify(rootDir, args, options) {
|
|
|
51636
51802
|
);
|
|
51637
51803
|
}
|
|
51638
51804
|
if (options.evidenceFile) {
|
|
51639
|
-
const evidencePath =
|
|
51805
|
+
const evidencePath = path76.isAbsolute(options.evidenceFile) ? options.evidenceFile : path76.resolve(rootDir, options.evidenceFile);
|
|
51640
51806
|
if (!await pathExists16(evidencePath)) {
|
|
51641
51807
|
return invalidArg(
|
|
51642
51808
|
options,
|
|
@@ -51696,14 +51862,14 @@ async function workflowVerify(rootDir, args, options) {
|
|
|
51696
51862
|
}
|
|
51697
51863
|
async function commitVerificationTransition(rootDir, meta, ledger) {
|
|
51698
51864
|
const ledgerPath = verificationLedgerPath(rootDir, meta.taskId);
|
|
51699
|
-
const metadataPath3 =
|
|
51865
|
+
const metadataPath3 = path76.join(
|
|
51700
51866
|
rootDir,
|
|
51701
51867
|
".mancode",
|
|
51702
51868
|
"workflows",
|
|
51703
51869
|
meta.taskId,
|
|
51704
51870
|
"metadata.json"
|
|
51705
51871
|
);
|
|
51706
|
-
const specPath =
|
|
51872
|
+
const specPath = path76.join(rootDir, ".mancode", "memory", "spec.md");
|
|
51707
51873
|
const [originalLedger, originalMetadata, originalSpec] = await Promise.all([
|
|
51708
51874
|
readOptionalText2(ledgerPath),
|
|
51709
51875
|
readFile49(metadataPath3, "utf-8"),
|
|
@@ -51867,7 +52033,7 @@ async function workflowReview(rootDir, args, options) {
|
|
|
51867
52033
|
}
|
|
51868
52034
|
async function commitReviewSkip(rootDir, meta, reason) {
|
|
51869
52035
|
const ledgerPath = reviewLedgerPath(rootDir, meta.taskId);
|
|
51870
|
-
const metadataPath3 =
|
|
52036
|
+
const metadataPath3 = path76.join(
|
|
51871
52037
|
rootDir,
|
|
51872
52038
|
".mancode",
|
|
51873
52039
|
"workflows",
|
|
@@ -52107,14 +52273,14 @@ async function workflowHandoff(rootDir, taskId, options) {
|
|
|
52107
52273
|
"solo handoff requires an undecided in-progress workflow at step 4 with ready requirements"
|
|
52108
52274
|
);
|
|
52109
52275
|
}
|
|
52110
|
-
const workflowPath =
|
|
52111
|
-
if (!await pathExists16(
|
|
52276
|
+
const workflowPath = path76.join(rootDir, ".mancode", "workflows", taskId);
|
|
52277
|
+
if (!await pathExists16(path76.join(workflowPath, "requirements.md")) || !await pathExists16(path76.join(workflowPath, "plan.md"))) {
|
|
52112
52278
|
return invalidArg(
|
|
52113
52279
|
options,
|
|
52114
52280
|
"solo handoff requires requirements.md and plan.md"
|
|
52115
52281
|
);
|
|
52116
52282
|
}
|
|
52117
|
-
const statePath =
|
|
52283
|
+
const statePath = path76.join(rootDir, ".mancode", "state.json");
|
|
52118
52284
|
let originalState;
|
|
52119
52285
|
let state;
|
|
52120
52286
|
try {
|
|
@@ -52189,7 +52355,7 @@ async function workflowCompleteHandoff(rootDir, taskId, options) {
|
|
|
52189
52355
|
`workflow is not an active solo handoff: ${taskId}`
|
|
52190
52356
|
);
|
|
52191
52357
|
}
|
|
52192
|
-
const statePath =
|
|
52358
|
+
const statePath = path76.join(rootDir, ".mancode", "state.json");
|
|
52193
52359
|
let originalState;
|
|
52194
52360
|
let state;
|
|
52195
52361
|
try {
|
|
@@ -52256,14 +52422,14 @@ async function workflowDecide(rootDir, taskId, options) {
|
|
|
52256
52422
|
`workflow is not ready for a plan-only decision: ${taskId}`
|
|
52257
52423
|
);
|
|
52258
52424
|
}
|
|
52259
|
-
const workflowPath =
|
|
52260
|
-
if (!await pathExists16(
|
|
52425
|
+
const workflowPath = path76.join(rootDir, ".mancode", "workflows", taskId);
|
|
52426
|
+
if (!await pathExists16(path76.join(workflowPath, "requirements.md")) || !await pathExists16(path76.join(workflowPath, "plan.md"))) {
|
|
52261
52427
|
return invalidArg(
|
|
52262
52428
|
options,
|
|
52263
52429
|
"plan-only requires requirements.md and plan.md"
|
|
52264
52430
|
);
|
|
52265
52431
|
}
|
|
52266
|
-
const statePath =
|
|
52432
|
+
const statePath = path76.join(rootDir, ".mancode", "state.json");
|
|
52267
52433
|
let originalState;
|
|
52268
52434
|
let state;
|
|
52269
52435
|
try {
|
|
@@ -52319,14 +52485,14 @@ async function workflowDecide(rootDir, taskId, options) {
|
|
|
52319
52485
|
return EXIT_OK11;
|
|
52320
52486
|
}
|
|
52321
52487
|
async function commitPlanningTransition(args) {
|
|
52322
|
-
const metadataPath3 =
|
|
52488
|
+
const metadataPath3 = path76.join(
|
|
52323
52489
|
args.rootDir,
|
|
52324
52490
|
".mancode",
|
|
52325
52491
|
"workflows",
|
|
52326
52492
|
args.taskId,
|
|
52327
52493
|
"metadata.json"
|
|
52328
52494
|
);
|
|
52329
|
-
const specPath =
|
|
52495
|
+
const specPath = path76.join(args.rootDir, ".mancode", "memory", "spec.md");
|
|
52330
52496
|
let originalMetadata;
|
|
52331
52497
|
let originalSpec;
|
|
52332
52498
|
try {
|