@moda-ai/cli 1.55.9 → 1.55.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{cli-mx9r1689.js → cli-0qnghzg4.js} +1 -1
- package/dist/{cli-tw8jj190.js → cli-4f0p8erk.js} +1 -1
- package/dist/{cli-fhfdnvh4.js → cli-7s48d6ty.js} +2 -2
- package/dist/{cli-sjc132j8.js → cli-d3c95kks.js} +8 -8
- package/dist/{cli-4af3thx7.js → cli-v27q5dvh.js} +8 -8
- package/dist/cli.js +43 -244
- package/dist/{harness-yshh2pgj.js → harness-0tnqw849.js} +2 -2
- package/dist/{harness-github-actions-73a08nct.js → harness-github-actions-wpkr7jjr.js} +2 -2
- package/dist/{index-f3k9jgrt.js → index-jqexf7kn.js} +9 -21
- package/dist/prompt-source-mcp.js +3 -3
- package/dist/{provision-parsn3xg.js → provision-5pkn25hh.js} +3 -3
- package/package.json +1 -2
- package/skills/integration/index.json +2 -2
- package/skills/moda-cli/SKILL.md +2 -2
- package/hooks/moda-snapshot.sh +0 -41
|
@@ -1935,4 +1935,4 @@ function createCommandContext(input, options = {}) {
|
|
|
1935
1935
|
};
|
|
1936
1936
|
}
|
|
1937
1937
|
|
|
1938
|
-
export { PROD_BASE_URL, DEFAULT_INGEST_URL, getModaPaths, getModaDir, isLoopbackBaseUrl,
|
|
1938
|
+
export { PROD_BASE_URL, DEFAULT_INGEST_URL, getModaPaths, getModaDir, isLoopbackBaseUrl, describeBaseUrlSource, loadProfileConfig, saveProfileConfig, getActiveProfile, setActiveProfile, upsertProfile, clearStoredApiKeyCredentials, secretFilePathFromRef, resolveSecretReference, resolveApiKeyFromActiveProfile, resolveTenantIdFromActiveProfile, ensureSecretFilePermissions, writeSecretJsonFile, CliInputError, CliAccessError, CliInputRequiredError, CliAuthError, CliCancellationError, isNetworkLikeError, isApiLikeError, VERSION, MODA_BASE_URL, loadCliConfig, saveCliConfig, resolveApiKey, embeddedTenantIdFromApiKey, resolveIngestUrl2 as resolveIngestUrl, resolveTenantId, resolveApiTenantId, resolveModaBaseUrl, validateConfig, recordApiRequest, getApiRequestCount, resetApiRequestCount, MAX_SCANNED_FILE_BYTES, DEFAULT_MAX_INVENTORY_FILES, DEFAULT_MAX_INVENTORY_TEXT_BYTES, MAX_RECORDED_SKIPS, SKIPPED_DIRS, isSkippedDir, isSkippedPathPrefix, isEvalLikePath, shouldInventoryFile, isTextFile, isSecretishPath, SECRET_KEYS, redactDeep, redactString, packSnapshot, EXIT_OK, EXIT_ERROR, EXIT_DEGRADED, EXIT_AUTH_REQUIRED, EXIT_INPUT_REQUIRED, EXIT_CANCELLED, AGENT_ERROR_CODES, wasOutputCancelled, safeWriteStdout, safeWriteStderr, explicitOutputMode, resolveOutputMode, createCliOutput, agentEnvelopeFits, agentMaxOutputBytes, parseBooleanFlagValue, stringOption, createCommandContext };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
authFetch,
|
|
3
3
|
getCachedLoginContext
|
|
4
|
-
} from "./cli-
|
|
4
|
+
} from "./cli-4f0p8erk.js";
|
|
5
5
|
import {
|
|
6
6
|
CliAccessError,
|
|
7
7
|
CliInputError,
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
resolveTenantIdFromActiveProfile,
|
|
17
17
|
saveCliConfig,
|
|
18
18
|
writeSecretJsonFile
|
|
19
|
-
} from "./cli-
|
|
19
|
+
} from "./cli-0qnghzg4.js";
|
|
20
20
|
|
|
21
21
|
// src/init/tenant.ts
|
|
22
22
|
import { randomUUID } from "node:crypto";
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
safePromptEvidencePath,
|
|
22
22
|
scanHarness,
|
|
23
23
|
setPlatformTenantOverride
|
|
24
|
-
} from "./cli-
|
|
24
|
+
} from "./cli-v27q5dvh.js";
|
|
25
25
|
import {
|
|
26
26
|
SKILL_SOURCE_HARNESS,
|
|
27
27
|
SKILL_SOURCE_INTEGRATION_BUNDLED,
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
import {
|
|
35
35
|
isAuthSessionValid,
|
|
36
36
|
loadAuthSession
|
|
37
|
-
} from "./cli-
|
|
37
|
+
} from "./cli-4f0p8erk.js";
|
|
38
38
|
import {
|
|
39
39
|
CliInputError,
|
|
40
40
|
EXIT_ERROR,
|
|
@@ -54,7 +54,7 @@ import {
|
|
|
54
54
|
resolveTenantId,
|
|
55
55
|
secretFilePathFromRef,
|
|
56
56
|
validateConfig
|
|
57
|
-
} from "./cli-
|
|
57
|
+
} from "./cli-0qnghzg4.js";
|
|
58
58
|
import {
|
|
59
59
|
__commonJS,
|
|
60
60
|
__require,
|
|
@@ -6752,7 +6752,7 @@ async function runPromptSyncExclusive(flags, profileOptions, options) {
|
|
|
6752
6752
|
const analyzedDefinitions = new Map;
|
|
6753
6753
|
if (flags["no-analyze"] !== "true") {
|
|
6754
6754
|
options.onProgress?.("Analyzing prompt sources before sync.");
|
|
6755
|
-
const { analyzeHarnessPrompts } = await import("./harness-
|
|
6755
|
+
const { analyzeHarnessPrompts } = await import("./harness-0tnqw849.js");
|
|
6756
6756
|
const result = await analyzeHarnessPrompts({
|
|
6757
6757
|
rootDir: process.cwd(),
|
|
6758
6758
|
existing: established.flatMap((prompt) => prompt.sourceDefinition ? [prompt.sourceDefinition.source] : []),
|
|
@@ -7082,7 +7082,7 @@ async function migratePromptManifest(options = {}) {
|
|
|
7082
7082
|
let addedSources = [];
|
|
7083
7083
|
let pendingSources = [];
|
|
7084
7084
|
if (options.discover) {
|
|
7085
|
-
const { analyzeHarnessPrompts } = await import("./harness-
|
|
7085
|
+
const { analyzeHarnessPrompts } = await import("./harness-0tnqw849.js");
|
|
7086
7086
|
const result = await analyzeHarnessPrompts({
|
|
7087
7087
|
rootDir: root,
|
|
7088
7088
|
existing: manifest.sources,
|
|
@@ -8444,7 +8444,7 @@ async function runSkillRegistryCommand(sub, positionals, flags, context) {
|
|
|
8444
8444
|
|
|
8445
8445
|
// src/doctor.ts
|
|
8446
8446
|
import { createHash as createHash3 } from "node:crypto";
|
|
8447
|
-
import { existsSync as existsSync5, readFileSync as readFileSync4
|
|
8447
|
+
import { existsSync as existsSync5, readFileSync as readFileSync4 } from "node:fs";
|
|
8448
8448
|
import { join as join4 } from "node:path";
|
|
8449
8449
|
async function runDoctorCommand(context) {
|
|
8450
8450
|
const report = await buildDoctorReport(context, {
|
|
@@ -8483,7 +8483,7 @@ async function runStatusCommand(context) {
|
|
|
8483
8483
|
harness: checkStatus(report.checks, "harness_manifest_current"),
|
|
8484
8484
|
harnessSync: checkStatus(report.checks, "harness_sync_state_present"),
|
|
8485
8485
|
harnessReport: "skipped",
|
|
8486
|
-
shadowSpark:
|
|
8486
|
+
shadowSpark: "skipped",
|
|
8487
8487
|
prompts: checkStatus(report.checks, "prompts_discovered"),
|
|
8488
8488
|
skills: checkStatus(report.checks, "skills_discovered"),
|
|
8489
8489
|
topBrokenCheck: topBroken ? {
|
|
@@ -9102,7 +9102,7 @@ function recentDataFlowCheck(overview) {
|
|
|
9102
9102
|
{ label: "last_event_at", value: lastEventAt ?? "none" }
|
|
9103
9103
|
],
|
|
9104
9104
|
remediation: hasData ? undefined : "No recent Moda data was visible in the overview window.",
|
|
9105
|
-
nextCommand: hasData ? undefined : "moda
|
|
9105
|
+
nextCommand: hasData ? undefined : "moda init"
|
|
9106
9106
|
};
|
|
9107
9107
|
}
|
|
9108
9108
|
function numberAt(value, path) {
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
resolveTenantId,
|
|
28
28
|
shouldInventoryFile,
|
|
29
29
|
stringOption
|
|
30
|
-
} from "./cli-
|
|
30
|
+
} from "./cli-0qnghzg4.js";
|
|
31
31
|
import {
|
|
32
32
|
__commonJS,
|
|
33
33
|
__require,
|
|
@@ -193387,12 +193387,12 @@ function assertHarnessGraphSyncSize(graph) {
|
|
|
193387
193387
|
// ../../packages/messaging/messaging.json
|
|
193388
193388
|
var messaging_default = {
|
|
193389
193389
|
$schema: "./messaging.schema.json",
|
|
193390
|
-
version: "1.0.
|
|
193390
|
+
version: "1.0.3",
|
|
193391
193391
|
locked_on: "2026-10-14",
|
|
193392
193392
|
approved_by: "mo",
|
|
193393
|
-
source: "Branding project docs/positioning.md v1.0.
|
|
193393
|
+
source: "Branding project docs/positioning.md v1.0.3",
|
|
193394
193394
|
canonical_strings: {
|
|
193395
|
-
version: "1.0.
|
|
193395
|
+
version: "1.0.3",
|
|
193396
193396
|
locked_on: "2026-10-14",
|
|
193397
193397
|
approved_by: "mo",
|
|
193398
193398
|
strings: [
|
|
@@ -193419,7 +193419,7 @@ var messaging_default = {
|
|
|
193419
193419
|
text: "Production monitoring and evals for AI agents.",
|
|
193420
193420
|
match: "contains_ci",
|
|
193421
193421
|
surfaces: [
|
|
193422
|
-
"apps/moda-frontend/
|
|
193422
|
+
"apps/moda-frontend/app/llms.txt/route.ts (after the tagline)",
|
|
193423
193423
|
"every bio, package description and directory listing below"
|
|
193424
193424
|
]
|
|
193425
193425
|
},
|
|
@@ -193598,7 +193598,7 @@ var messaging_default = {
|
|
|
193598
193598
|
]
|
|
193599
193599
|
},
|
|
193600
193600
|
banned_phrases: {
|
|
193601
|
-
version: "1.0.
|
|
193601
|
+
version: "1.0.3",
|
|
193602
193602
|
phrases: [
|
|
193603
193603
|
{
|
|
193604
193604
|
id: "fixes_your_agent",
|
|
@@ -193775,7 +193775,7 @@ var messaging_default = {
|
|
|
193775
193775
|
]
|
|
193776
193776
|
},
|
|
193777
193777
|
terminology: {
|
|
193778
|
-
version: "1.0.
|
|
193778
|
+
version: "1.0.3",
|
|
193779
193779
|
terms: [
|
|
193780
193780
|
{
|
|
193781
193781
|
use: "trace",
|
|
@@ -194777,7 +194777,7 @@ async function runHarnessCommand(context) {
|
|
|
194777
194777
|
throw new CliInputError("Focused remote prompt analysis is not supported yet.", "Use local --analyst=claude|codex|cursor|local-scan, or drop --concern for a full remote report.");
|
|
194778
194778
|
}
|
|
194779
194779
|
if (context.flags["github-actions"] === "true") {
|
|
194780
|
-
const { runGithubActionsAnalyze } = await import("./harness-github-actions-
|
|
194780
|
+
const { runGithubActionsAnalyze } = await import("./harness-github-actions-wpkr7jjr.js");
|
|
194781
194781
|
const result = await runGithubActionsAnalyze(rootDir, {
|
|
194782
194782
|
writeReport: (report2) => {
|
|
194783
194783
|
const normalized = normalizeHarnessReport(report2);
|
package/dist/cli.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
runPromptsCommand,
|
|
9
9
|
runSkillsCommand,
|
|
10
10
|
runStatusCommand
|
|
11
|
-
} from "./cli-
|
|
11
|
+
} from "./cli-d3c95kks.js";
|
|
12
12
|
import"./cli-mm48br00.js";
|
|
13
13
|
import {
|
|
14
14
|
ApiError,
|
|
@@ -39,7 +39,7 @@ import {
|
|
|
39
39
|
terminalStyles,
|
|
40
40
|
unknownSignalsSubcommandError,
|
|
41
41
|
validateHarnessReport
|
|
42
|
-
} from "./cli-
|
|
42
|
+
} from "./cli-v27q5dvh.js";
|
|
43
43
|
import"./cli-ssfq84k5.js";
|
|
44
44
|
import {
|
|
45
45
|
authFetch,
|
|
@@ -48,7 +48,7 @@ import {
|
|
|
48
48
|
loadAuthSession,
|
|
49
49
|
login,
|
|
50
50
|
revokeCliSessionToken
|
|
51
|
-
} from "./cli-
|
|
51
|
+
} from "./cli-4f0p8erk.js";
|
|
52
52
|
import {
|
|
53
53
|
AGENT_ERROR_CODES,
|
|
54
54
|
CliAccessError,
|
|
@@ -68,7 +68,6 @@ import {
|
|
|
68
68
|
VERSION,
|
|
69
69
|
agentEnvelopeFits,
|
|
70
70
|
agentMaxOutputBytes,
|
|
71
|
-
assertValidProfileName,
|
|
72
71
|
clearStoredApiKeyCredentials,
|
|
73
72
|
createCliOutput,
|
|
74
73
|
createCommandContext,
|
|
@@ -101,9 +100,8 @@ import {
|
|
|
101
100
|
setActiveProfile,
|
|
102
101
|
upsertProfile,
|
|
103
102
|
validateConfig,
|
|
104
|
-
wasOutputCancelled
|
|
105
|
-
|
|
106
|
-
} from "./cli-mx9r1689.js";
|
|
103
|
+
wasOutputCancelled
|
|
104
|
+
} from "./cli-0qnghzg4.js";
|
|
107
105
|
import {
|
|
108
106
|
__require
|
|
109
107
|
} from "./cli-0v6na3yp.js";
|
|
@@ -4946,124 +4944,6 @@ async function probeApiKey(key, options = {}) {
|
|
|
4946
4944
|
return { outcome: "live" };
|
|
4947
4945
|
}
|
|
4948
4946
|
|
|
4949
|
-
// src/keys.ts
|
|
4950
|
-
import { createHash as createHash2 } from "node:crypto";
|
|
4951
|
-
import { existsSync as existsSync3, readFileSync as readFileSync4 } from "node:fs";
|
|
4952
|
-
import { join as join3 } from "node:path";
|
|
4953
|
-
function keySecretRef(profile, keyId) {
|
|
4954
|
-
assertValidProfileName(profile);
|
|
4955
|
-
assertSafeKeyId(keyId);
|
|
4956
|
-
return `file:secrets/api-keys/${profile}/${keyId}.json`;
|
|
4957
|
-
}
|
|
4958
|
-
function createLocalKeyDescriptor(input) {
|
|
4959
|
-
assertValidProfileName(input.profile);
|
|
4960
|
-
const now = input.now ?? new Date;
|
|
4961
|
-
const id = stableKeyId(input.profile, input.name, now);
|
|
4962
|
-
return {
|
|
4963
|
-
id,
|
|
4964
|
-
profile: input.profile,
|
|
4965
|
-
name: input.name,
|
|
4966
|
-
purpose: input.purpose ?? "data_api",
|
|
4967
|
-
environment: input.environment,
|
|
4968
|
-
tenant_id: input.tenant_id,
|
|
4969
|
-
workspace_id: input.workspace_id,
|
|
4970
|
-
secret_ref: input.secret_ref ?? keySecretRef(input.profile, id),
|
|
4971
|
-
status: "active",
|
|
4972
|
-
created_at: now.toISOString()
|
|
4973
|
-
};
|
|
4974
|
-
}
|
|
4975
|
-
function validateKeyDescriptor(descriptor) {
|
|
4976
|
-
assertValidProfileName(descriptor.profile);
|
|
4977
|
-
assertSafeKeyId(descriptor.id);
|
|
4978
|
-
if (!descriptor.name.trim()) {
|
|
4979
|
-
throw new Error("Key name is required.");
|
|
4980
|
-
}
|
|
4981
|
-
if (descriptor.status !== "active" && descriptor.status !== "rotating" && descriptor.status !== "revoked") {
|
|
4982
|
-
throw new Error(`Invalid key status '${descriptor.status}'.`);
|
|
4983
|
-
}
|
|
4984
|
-
if (descriptor.purpose !== "data_api" && descriptor.purpose !== "ingest" && descriptor.purpose !== "automation") {
|
|
4985
|
-
throw new Error(`Invalid key purpose '${descriptor.purpose}'.`);
|
|
4986
|
-
}
|
|
4987
|
-
if (descriptor.environment !== "local" && descriptor.environment !== "dev" && descriptor.environment !== "staging" && descriptor.environment !== "prod") {
|
|
4988
|
-
throw new Error(`Invalid key environment '${descriptor.environment}'.`);
|
|
4989
|
-
}
|
|
4990
|
-
if (!descriptor.secret_ref.startsWith("file:")) {
|
|
4991
|
-
throw new Error("Local key descriptors must point to a file: secret ref.");
|
|
4992
|
-
}
|
|
4993
|
-
}
|
|
4994
|
-
function writeLocalApiKeySecret(descriptor, apiKey, options = {}) {
|
|
4995
|
-
validateKeyDescriptor(descriptor);
|
|
4996
|
-
if (!apiKey.trim()) {
|
|
4997
|
-
throw new Error("API key value is required.");
|
|
4998
|
-
}
|
|
4999
|
-
const path = secretFilePathFromRef(descriptor.secret_ref, options);
|
|
5000
|
-
if (!path) {
|
|
5001
|
-
throw new Error(`Unsupported key secret reference: ${descriptor.secret_ref}`);
|
|
5002
|
-
}
|
|
5003
|
-
writeSecretJsonFile(path, {
|
|
5004
|
-
value: apiKey,
|
|
5005
|
-
key_id: descriptor.id,
|
|
5006
|
-
profile: descriptor.profile,
|
|
5007
|
-
purpose: descriptor.purpose,
|
|
5008
|
-
created_at: descriptor.created_at
|
|
5009
|
-
});
|
|
5010
|
-
return path;
|
|
5011
|
-
}
|
|
5012
|
-
function keyDescriptorStorePath(options = {}) {
|
|
5013
|
-
return join3(getModaPaths(options).dir, "keys.json");
|
|
5014
|
-
}
|
|
5015
|
-
function loadLocalKeyDescriptors(options = {}) {
|
|
5016
|
-
const path = keyDescriptorStorePath(options);
|
|
5017
|
-
try {
|
|
5018
|
-
if (!existsSync3(path))
|
|
5019
|
-
return [];
|
|
5020
|
-
const parsed = JSON.parse(readFileSync4(path, "utf8"));
|
|
5021
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
5022
|
-
return [];
|
|
5023
|
-
}
|
|
5024
|
-
const keys = parsed.keys;
|
|
5025
|
-
if (!Array.isArray(keys))
|
|
5026
|
-
return [];
|
|
5027
|
-
return keys.filter((key) => {
|
|
5028
|
-
try {
|
|
5029
|
-
validateKeyDescriptor(key);
|
|
5030
|
-
return true;
|
|
5031
|
-
} catch {
|
|
5032
|
-
return false;
|
|
5033
|
-
}
|
|
5034
|
-
});
|
|
5035
|
-
} catch {
|
|
5036
|
-
return [];
|
|
5037
|
-
}
|
|
5038
|
-
}
|
|
5039
|
-
function saveLocalKeyDescriptors(keys, options = {}) {
|
|
5040
|
-
for (const key of keys)
|
|
5041
|
-
validateKeyDescriptor(key);
|
|
5042
|
-
writeSecretJsonFile(keyDescriptorStorePath(options), {
|
|
5043
|
-
version: 1,
|
|
5044
|
-
keys
|
|
5045
|
-
});
|
|
5046
|
-
}
|
|
5047
|
-
function upsertLocalKeyDescriptor(descriptor, options = {}) {
|
|
5048
|
-
validateKeyDescriptor(descriptor);
|
|
5049
|
-
const keys = loadLocalKeyDescriptors(options);
|
|
5050
|
-
const next = [
|
|
5051
|
-
...keys.filter((key) => key.id !== descriptor.id),
|
|
5052
|
-
descriptor
|
|
5053
|
-
].sort((a, b) => a.created_at.localeCompare(b.created_at));
|
|
5054
|
-
saveLocalKeyDescriptors(next, options);
|
|
5055
|
-
return next;
|
|
5056
|
-
}
|
|
5057
|
-
function stableKeyId(profile, name, now) {
|
|
5058
|
-
const hash = createHash2("sha256").update(`${profile}\x00${name}\x00${now.toISOString()}`).digest("hex").slice(0, 12);
|
|
5059
|
-
return `key_${hash}`;
|
|
5060
|
-
}
|
|
5061
|
-
function assertSafeKeyId(keyId) {
|
|
5062
|
-
if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/.test(keyId)) {
|
|
5063
|
-
throw new Error(`Invalid key id '${keyId}'. Use letters, numbers, dots, dashes, or underscores.`);
|
|
5064
|
-
}
|
|
5065
|
-
}
|
|
5066
|
-
|
|
5067
4947
|
// src/profile-commands.ts
|
|
5068
4948
|
var ONLINE_PROBE_TIMEOUT_MS = 5000;
|
|
5069
4949
|
function subcommand(context) {
|
|
@@ -5459,62 +5339,14 @@ async function runConfigCommand(context) {
|
|
|
5459
5339
|
});
|
|
5460
5340
|
return { exitCode: 0 };
|
|
5461
5341
|
}
|
|
5462
|
-
var KEYS_LOCAL_ONLY_NOTE = "moda keys manages local key descriptors in ~/.moda only; it does not list or change your tenant's server-side API keys (see Settings → Ingestion keys in the dashboard).";
|
|
5463
|
-
async function runKeysCommand(context) {
|
|
5464
|
-
switch (subcommand(context)) {
|
|
5465
|
-
case "list": {
|
|
5466
|
-
const profile = context.profile ?? (context.env.MODA_PROFILE?.trim() || undefined) ?? loadProfileConfig({ env: context.env }).active_profile;
|
|
5467
|
-
const keys = loadLocalKeyDescriptors({ env: context.env }).filter((key) => !profile || key.profile === profile);
|
|
5468
|
-
context.output.writeData({
|
|
5469
|
-
scope: "local_descriptors",
|
|
5470
|
-
profile,
|
|
5471
|
-
keys
|
|
5472
|
-
}, {
|
|
5473
|
-
warnings: [KEYS_LOCAL_ONLY_NOTE]
|
|
5474
|
-
});
|
|
5475
|
-
return { exitCode: 0 };
|
|
5476
|
-
}
|
|
5477
|
-
case "create": {
|
|
5478
|
-
const active = getActiveProfile({ profile: context.profile, env: context.env });
|
|
5479
|
-
const name = flag(context, "name") ?? `${active.name}-${Date.now()}`;
|
|
5480
|
-
const descriptor = createLocalKeyDescriptor({
|
|
5481
|
-
profile: active.name,
|
|
5482
|
-
environment: active.environment,
|
|
5483
|
-
name,
|
|
5484
|
-
purpose: "data_api",
|
|
5485
|
-
tenant_id: active.tenant_id,
|
|
5486
|
-
workspace_id: active.workspace_id
|
|
5487
|
-
});
|
|
5488
|
-
const value = flag(context, "value");
|
|
5489
|
-
const secretPath = value ? writeLocalApiKeySecret(descriptor, value, { env: context.env }) : undefined;
|
|
5490
|
-
upsertLocalKeyDescriptor(descriptor, { env: context.env });
|
|
5491
|
-
context.output.writeData({
|
|
5492
|
-
key: descriptor,
|
|
5493
|
-
secret_path: secretPath,
|
|
5494
|
-
scope: "local_descriptors"
|
|
5495
|
-
}, {
|
|
5496
|
-
warnings: [KEYS_LOCAL_ONLY_NOTE]
|
|
5497
|
-
});
|
|
5498
|
-
return { exitCode: 0 };
|
|
5499
|
-
}
|
|
5500
|
-
case "rotate":
|
|
5501
|
-
case "revoke": {
|
|
5502
|
-
const action = subcommand(context);
|
|
5503
|
-
const keyId = requirePositional(context, 1, `Usage: moda keys ${action} <key_id>`);
|
|
5504
|
-
throw new CliInputError(`moda keys ${action} is not supported: the CLI cannot ${action} server-side API keys (${keyId} was not changed).`, "Manage API keys in the dashboard at Settings → Ingestion keys.");
|
|
5505
|
-
}
|
|
5506
|
-
default:
|
|
5507
|
-
throw unknownSubcommandError("keys", subcommand(context), ["list", "create", "rotate", "revoke"]);
|
|
5508
|
-
}
|
|
5509
|
-
}
|
|
5510
5342
|
|
|
5511
5343
|
// src/agent.ts
|
|
5512
|
-
import { existsSync as
|
|
5513
|
-
import { join as
|
|
5344
|
+
import { existsSync as existsSync3, readFileSync as readFileSync4, statSync as statSync2 } from "node:fs";
|
|
5345
|
+
import { join as join3, relative as relative2, resolve as resolve3 } from "node:path";
|
|
5514
5346
|
var MODA_DIR = ".moda";
|
|
5515
|
-
var HARNESS_PATH =
|
|
5516
|
-
var HARNESS_REPORT_MARKDOWN_PATH =
|
|
5517
|
-
var HARNESS_SUMMARY_PATH =
|
|
5347
|
+
var HARNESS_PATH = join3(MODA_DIR, "harness.json");
|
|
5348
|
+
var HARNESS_REPORT_MARKDOWN_PATH = join3(MODA_DIR, "HARNESS_REPORT.md");
|
|
5349
|
+
var HARNESS_SUMMARY_PATH = join3(MODA_DIR, "HARNESS.md");
|
|
5518
5350
|
async function runAgentCommand(context) {
|
|
5519
5351
|
const subcommand2 = context.positionals[0] ?? "context";
|
|
5520
5352
|
switch (subcommand2) {
|
|
@@ -5558,22 +5390,6 @@ async function runAgentCommand(context) {
|
|
|
5558
5390
|
});
|
|
5559
5391
|
return { exitCode: 0 };
|
|
5560
5392
|
}
|
|
5561
|
-
case "ask": {
|
|
5562
|
-
const loaded = await buildAgentContext(context);
|
|
5563
|
-
const question = context.positionals.slice(1).join(" ").trim() || context.flags.question;
|
|
5564
|
-
context.output.writeData({
|
|
5565
|
-
schemaVersion: "agent_ask.v0.1",
|
|
5566
|
-
generatedAt: loaded.payload.generatedAt,
|
|
5567
|
-
question: question || null,
|
|
5568
|
-
answer: "Moda CLI can provide local harness context today. Cloud intelligence for free-form production questions belongs to the future Moda Ask layer.",
|
|
5569
|
-
recommendedActions: loaded.payload.recommendedActions,
|
|
5570
|
-
nextCommands: loaded.payload.nextCommands,
|
|
5571
|
-
evidenceRefs: loaded.payload.evidenceRefs
|
|
5572
|
-
}, agentWriteOptions(loaded, {
|
|
5573
|
-
summary: "Returned local Moda context and next commands for the requested agent question."
|
|
5574
|
-
}));
|
|
5575
|
-
return { exitCode: 0 };
|
|
5576
|
-
}
|
|
5577
5393
|
default:
|
|
5578
5394
|
throw new CliInputError(`Unknown agent subcommand '${subcommand2}'`, "Usage: moda agent context|next-action|evidence (for production issues use moda investigate)");
|
|
5579
5395
|
}
|
|
@@ -5618,7 +5434,7 @@ async function buildAgentContext(context) {
|
|
|
5618
5434
|
},
|
|
5619
5435
|
report: reportState.state,
|
|
5620
5436
|
sync: syncState ? {
|
|
5621
|
-
path:
|
|
5437
|
+
path: join3(MODA_DIR, "sync-state.json"),
|
|
5622
5438
|
exists: true,
|
|
5623
5439
|
source: syncState.source,
|
|
5624
5440
|
updatedAt: syncState.updatedAt,
|
|
@@ -5626,7 +5442,7 @@ async function buildAgentContext(context) {
|
|
|
5626
5442
|
remoteHarnessId: syncState.remote.harnessId,
|
|
5627
5443
|
remoteVersionId: syncState.remote.versionId
|
|
5628
5444
|
} : {
|
|
5629
|
-
path:
|
|
5445
|
+
path: join3(MODA_DIR, "sync-state.json"),
|
|
5630
5446
|
exists: false
|
|
5631
5447
|
}
|
|
5632
5448
|
},
|
|
@@ -5676,18 +5492,18 @@ function summarizeAgentContext(payload, noun) {
|
|
|
5676
5492
|
return `Local Moda ${noun} is healthy with ${agents} runtime agent(s).`;
|
|
5677
5493
|
}
|
|
5678
5494
|
function readHarnessGraphIfPresent(cwd) {
|
|
5679
|
-
const path =
|
|
5680
|
-
if (!
|
|
5495
|
+
const path = join3(cwd, HARNESS_PATH);
|
|
5496
|
+
if (!existsSync3(path))
|
|
5681
5497
|
return;
|
|
5682
5498
|
try {
|
|
5683
|
-
return JSON.parse(
|
|
5499
|
+
return JSON.parse(readFileSync4(path, "utf8"));
|
|
5684
5500
|
} catch {
|
|
5685
5501
|
return;
|
|
5686
5502
|
}
|
|
5687
5503
|
}
|
|
5688
5504
|
function readHarnessReportState(cwd) {
|
|
5689
|
-
const path =
|
|
5690
|
-
if (!
|
|
5505
|
+
const path = join3(cwd, HARNESS_REPORT_PATH);
|
|
5506
|
+
if (!existsSync3(path)) {
|
|
5691
5507
|
return {
|
|
5692
5508
|
state: {
|
|
5693
5509
|
path: HARNESS_REPORT_PATH,
|
|
@@ -5731,11 +5547,11 @@ function readHarnessReportState(cwd) {
|
|
|
5731
5547
|
}
|
|
5732
5548
|
}
|
|
5733
5549
|
function readApproval(cwd) {
|
|
5734
|
-
const path =
|
|
5735
|
-
if (!
|
|
5550
|
+
const path = join3(cwd, HARNESS_REPORT_APPROVAL_PATH);
|
|
5551
|
+
if (!existsSync3(path))
|
|
5736
5552
|
return;
|
|
5737
5553
|
try {
|
|
5738
|
-
return JSON.parse(
|
|
5554
|
+
return JSON.parse(readFileSync4(path, "utf8"));
|
|
5739
5555
|
} catch {
|
|
5740
5556
|
return;
|
|
5741
5557
|
}
|
|
@@ -5811,9 +5627,9 @@ function existingArtifacts(cwd) {
|
|
|
5811
5627
|
[HARNESS_REPORT_PATH, "harness_report", "Cited harness analyst report."],
|
|
5812
5628
|
[HARNESS_REPORT_MARKDOWN_PATH, "harness_report_markdown", "Human-readable harness analyst report."],
|
|
5813
5629
|
[HARNESS_SUMMARY_PATH, "harness_summary", "Human-readable harness graph summary."],
|
|
5814
|
-
[
|
|
5815
|
-
[
|
|
5816
|
-
].flatMap(([path, kind, description]) =>
|
|
5630
|
+
[join3(MODA_DIR, "sync-state.json"), "sync_state", "Last local harness sync state."],
|
|
5631
|
+
[join3(MODA_DIR, "prompts.yml"), "prompt_manifest", "Local prompt discovery manifest."]
|
|
5632
|
+
].flatMap(([path, kind, description]) => existsSync3(join3(cwd, path)) ? [{ path, kind, description }] : []);
|
|
5817
5633
|
}
|
|
5818
5634
|
function expandEvidenceRef(ref, loaded, cwd) {
|
|
5819
5635
|
if (ref.startsWith("doctor:")) {
|
|
@@ -5894,9 +5710,9 @@ function readCitationExcerpt(cwd, citation) {
|
|
|
5894
5710
|
if (!citation.path || citation.type !== "file" && citation.type !== "generated_doc")
|
|
5895
5711
|
return citation.excerpt;
|
|
5896
5712
|
const absolute = safeResolve(cwd, citation.path);
|
|
5897
|
-
if (!absolute || !
|
|
5713
|
+
if (!absolute || !existsSync3(absolute))
|
|
5898
5714
|
return citation.excerpt;
|
|
5899
|
-
const text =
|
|
5715
|
+
const text = readFileSync4(absolute, "utf8");
|
|
5900
5716
|
if (citation.line && citation.line > 0) {
|
|
5901
5717
|
return text.split(/\r?\n/)[citation.line - 1] ?? citation.excerpt;
|
|
5902
5718
|
}
|
|
@@ -5907,13 +5723,13 @@ function readModaArtifact(cwd, artifactPath) {
|
|
|
5907
5723
|
throw new CliInputError(`Artifact '${artifactPath}' is outside .moda and cannot be expanded directly.`, "Use a citation evidence ref for source-file evidence.");
|
|
5908
5724
|
}
|
|
5909
5725
|
const absolute = safeResolve(cwd, artifactPath);
|
|
5910
|
-
if (!absolute || !
|
|
5726
|
+
if (!absolute || !existsSync3(absolute))
|
|
5911
5727
|
throw missingEvidence(`artifact:${artifactPath}`);
|
|
5912
5728
|
const size = statSync2(absolute).size;
|
|
5913
5729
|
return {
|
|
5914
5730
|
path: artifactPath,
|
|
5915
5731
|
bytes: size,
|
|
5916
|
-
text:
|
|
5732
|
+
text: readFileSync4(absolute, "utf8")
|
|
5917
5733
|
};
|
|
5918
5734
|
}
|
|
5919
5735
|
function safeResolve(cwd, path) {
|
|
@@ -5951,8 +5767,8 @@ function purposeForCommand(command) {
|
|
|
5951
5767
|
}
|
|
5952
5768
|
|
|
5953
5769
|
// src/production-intelligence.ts
|
|
5954
|
-
import { existsSync as
|
|
5955
|
-
import { join as
|
|
5770
|
+
import { existsSync as existsSync4, readFileSync as readFileSync5 } from "node:fs";
|
|
5771
|
+
import { join as join4 } from "node:path";
|
|
5956
5772
|
|
|
5957
5773
|
// src/ask-stream.ts
|
|
5958
5774
|
class AskStreamError extends Error {
|
|
@@ -7465,12 +7281,12 @@ function loadHarnessHints(cwd) {
|
|
|
7465
7281
|
skillPaths: new Map,
|
|
7466
7282
|
entrypointPaths: []
|
|
7467
7283
|
};
|
|
7468
|
-
const harnessPath =
|
|
7469
|
-
if (!
|
|
7284
|
+
const harnessPath = join4(cwd, ".moda", "harness.json");
|
|
7285
|
+
if (!existsSync4(harnessPath))
|
|
7470
7286
|
return hints;
|
|
7471
7287
|
hints.reportPath = ".moda/harness.json";
|
|
7472
7288
|
try {
|
|
7473
|
-
const parsed = JSON.parse(
|
|
7289
|
+
const parsed = JSON.parse(readFileSync5(harnessPath, "utf8"));
|
|
7474
7290
|
const graph = asRecord(parsed);
|
|
7475
7291
|
const artifacts = Array.isArray(graph?.artifacts) ? graph.artifacts : [];
|
|
7476
7292
|
for (const item of artifacts) {
|
|
@@ -7498,11 +7314,11 @@ function loadHarnessHints(cwd) {
|
|
|
7498
7314
|
return hints;
|
|
7499
7315
|
}
|
|
7500
7316
|
function localHarnessSummary(cwd) {
|
|
7501
|
-
const path =
|
|
7502
|
-
if (!
|
|
7317
|
+
const path = join4(cwd, ".moda", "harness.json");
|
|
7318
|
+
if (!existsSync4(path))
|
|
7503
7319
|
return null;
|
|
7504
7320
|
try {
|
|
7505
|
-
const parsed = JSON.parse(
|
|
7321
|
+
const parsed = JSON.parse(readFileSync5(path, "utf8"));
|
|
7506
7322
|
return {
|
|
7507
7323
|
harnessId: parsed.harnessId,
|
|
7508
7324
|
graphHash: parsed.graphHash,
|
|
@@ -7513,16 +7329,16 @@ function localHarnessSummary(cwd) {
|
|
|
7513
7329
|
}
|
|
7514
7330
|
}
|
|
7515
7331
|
function localSyncBrief(cwd, relativePath, label) {
|
|
7516
|
-
const path =
|
|
7517
|
-
if (!
|
|
7332
|
+
const path = join4(cwd, relativePath);
|
|
7333
|
+
if (!existsSync4(path)) {
|
|
7518
7334
|
return { status: "missing", summary: `${label} state not found`, path: relativePath };
|
|
7519
7335
|
}
|
|
7520
7336
|
return { status: "present", summary: `${label} state exists locally`, path: relativePath };
|
|
7521
7337
|
}
|
|
7522
7338
|
function localSkillBrief(cwd) {
|
|
7523
|
-
const claudeSkill =
|
|
7524
|
-
const cursorRules =
|
|
7525
|
-
if (
|
|
7339
|
+
const claudeSkill = join4(cwd, ".claude", "skills");
|
|
7340
|
+
const cursorRules = join4(cwd, ".cursor", "rules");
|
|
7341
|
+
if (existsSync4(claudeSkill) || existsSync4(cursorRules)) {
|
|
7526
7342
|
return { status: "present", summary: "Local agent skill/rule directory exists" };
|
|
7527
7343
|
}
|
|
7528
7344
|
return { status: "missing", summary: "No local agent skill/rule directory found" };
|
|
@@ -7960,7 +7776,6 @@ var RAW_BOOLEAN_FLAGS = new Set([
|
|
|
7960
7776
|
"no-clustering",
|
|
7961
7777
|
"no-analyze",
|
|
7962
7778
|
"improve-candidates",
|
|
7963
|
-
"hook-stdin",
|
|
7964
7779
|
"auto-generate",
|
|
7965
7780
|
"allow-no-agents",
|
|
7966
7781
|
"allow-any-model",
|
|
@@ -8099,8 +7914,6 @@ Commands:
|
|
|
8099
7914
|
profiles use <name> Switch active Moda profile
|
|
8100
7915
|
profiles create <name> Create or update a local Moda profile
|
|
8101
7916
|
profiles doctor [name] Validate a local Moda profile
|
|
8102
|
-
keys list List local key descriptors (not server-side API keys)
|
|
8103
|
-
keys create Create a local key descriptor
|
|
8104
7917
|
config show Show resolved Moda config
|
|
8105
7918
|
harness analyze Produce a cited structured harness report
|
|
8106
7919
|
harness pull Fetch a server-side analyze run (status, or result when done)
|
|
@@ -9245,7 +9058,7 @@ function normalizeBooleanFlags(target) {
|
|
|
9245
9058
|
}
|
|
9246
9059
|
return error;
|
|
9247
9060
|
}
|
|
9248
|
-
var PROFILE_MANAGING_COMMANDS = new Set(["profiles", "auth", "init", "provision", "status", "config", "
|
|
9061
|
+
var PROFILE_MANAGING_COMMANDS = new Set(["profiles", "auth", "init", "provision", "status", "config", "manifest", "agent", "doctor"]);
|
|
9249
9062
|
async function runProblemsRemainder(flags, context) {
|
|
9250
9063
|
const params = parseCommandFlags(ProblemsRemainderSchema, flagsToArgs(flags), "problems remainder");
|
|
9251
9064
|
const query2 = new URLSearchParams;
|
|
@@ -10492,8 +10305,6 @@ function initArtifactKind(file) {
|
|
|
10492
10305
|
return "prompt_manifest";
|
|
10493
10306
|
if (file.includes("workflow"))
|
|
10494
10307
|
return "ci_workflow";
|
|
10495
|
-
if (file.startsWith("~/"))
|
|
10496
|
-
return "agent_hook_config";
|
|
10497
10308
|
return "init_artifact";
|
|
10498
10309
|
}
|
|
10499
10310
|
var dataApiDefaults = {
|
|
@@ -10516,7 +10327,7 @@ var commandRegistry = createCommandRegistry([
|
|
|
10516
10327
|
resetApiRequestCountBeforeRun: true,
|
|
10517
10328
|
telemetry: "result",
|
|
10518
10329
|
handler: async (context) => {
|
|
10519
|
-
const { runInit } = await import("./index-
|
|
10330
|
+
const { runInit } = await import("./index-jqexf7kn.js");
|
|
10520
10331
|
if (context.outputMode === "agent-stream") {
|
|
10521
10332
|
context.output.writeEvent({
|
|
10522
10333
|
event: "started",
|
|
@@ -10557,7 +10368,7 @@ var commandRegistry = createCommandRegistry([
|
|
|
10557
10368
|
resetApiRequestCountBeforeRun: true,
|
|
10558
10369
|
telemetry: "result-and-error",
|
|
10559
10370
|
handler: async (context) => {
|
|
10560
|
-
const { runProvision } = await import("./provision-
|
|
10371
|
+
const { runProvision } = await import("./provision-5pkn25hh.js");
|
|
10561
10372
|
return runProvision(context, {
|
|
10562
10373
|
resumeCommand: buildResumeCommand("provision", context.rawFlags)
|
|
10563
10374
|
});
|
|
@@ -10731,18 +10542,6 @@ var commandRegistry = createCommandRegistry([
|
|
|
10731
10542
|
telemetry: "none",
|
|
10732
10543
|
handler: runConfigCommand
|
|
10733
10544
|
},
|
|
10734
|
-
{
|
|
10735
|
-
name: "keys",
|
|
10736
|
-
description: "Local key descriptors in ~/.moda only (not your server-side API keys; manage those in the dashboard)",
|
|
10737
|
-
examples: ["moda keys list", "moda keys create --name=local-dev"],
|
|
10738
|
-
auth: "none",
|
|
10739
|
-
outputModes: ["human", "json", "agent"],
|
|
10740
|
-
mutability: "write",
|
|
10741
|
-
validateConfigBeforeRun: false,
|
|
10742
|
-
resetApiRequestCountBeforeRun: false,
|
|
10743
|
-
telemetry: "none",
|
|
10744
|
-
handler: runKeysCommand
|
|
10745
|
-
},
|
|
10746
10545
|
{
|
|
10747
10546
|
name: "harness",
|
|
10748
10547
|
description: "Analyze, validate, approve, sync, delete, and explain the local multi-agent harness graph; register it for Replay Environments",
|
|
@@ -42,8 +42,8 @@ import {
|
|
|
42
42
|
writeHarnessAnalyzeResult,
|
|
43
43
|
writeHarnessArtifacts,
|
|
44
44
|
writeHumanProgress
|
|
45
|
-
} from "./cli-
|
|
46
|
-
import"./cli-
|
|
45
|
+
} from "./cli-v27q5dvh.js";
|
|
46
|
+
import"./cli-0qnghzg4.js";
|
|
47
47
|
import"./cli-0v6na3yp.js";
|
|
48
48
|
export {
|
|
49
49
|
writeHumanProgress,
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
initPrompts,
|
|
4
4
|
runPromptSync,
|
|
5
5
|
runSkillSync
|
|
6
|
-
} from "./cli-
|
|
6
|
+
} from "./cli-d3c95kks.js";
|
|
7
7
|
import"./cli-mm48br00.js";
|
|
8
8
|
import {
|
|
9
9
|
canonicalText,
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
runHarnessCommand,
|
|
25
25
|
startRemoteAnalyze,
|
|
26
26
|
stripAnsi
|
|
27
|
-
} from "./cli-
|
|
27
|
+
} from "./cli-v27q5dvh.js";
|
|
28
28
|
import {
|
|
29
29
|
bundledSkillsDir,
|
|
30
30
|
installIntegrationSkill,
|
|
@@ -36,14 +36,14 @@ import {
|
|
|
36
36
|
} from "./cli-ssfq84k5.js";
|
|
37
37
|
import {
|
|
38
38
|
selectTenantAndCreateKey
|
|
39
|
-
} from "./cli-
|
|
39
|
+
} from "./cli-7s48d6ty.js";
|
|
40
40
|
import {
|
|
41
41
|
ConnectCodeError,
|
|
42
42
|
connectWithCode,
|
|
43
43
|
loadAuthSession,
|
|
44
44
|
loadToken,
|
|
45
45
|
login
|
|
46
|
-
} from "./cli-
|
|
46
|
+
} from "./cli-4f0p8erk.js";
|
|
47
47
|
import {
|
|
48
48
|
CliAuthError,
|
|
49
49
|
CliInputError,
|
|
@@ -52,7 +52,7 @@ import {
|
|
|
52
52
|
recordApiRequest,
|
|
53
53
|
resolveIngestUrl,
|
|
54
54
|
resolveModaBaseUrl
|
|
55
|
-
} from "./cli-
|
|
55
|
+
} from "./cli-0qnghzg4.js";
|
|
56
56
|
import"./cli-0v6na3yp.js";
|
|
57
57
|
|
|
58
58
|
// src/init/index.ts
|
|
@@ -1751,7 +1751,6 @@ async function runInit(flags, options = {}) {
|
|
|
1751
1751
|
let setupPlan = [];
|
|
1752
1752
|
const renderPlan = () => {
|
|
1753
1753
|
setupPlan = buildSetupPlan({
|
|
1754
|
-
installHooks: false,
|
|
1755
1754
|
integrateSdk,
|
|
1756
1755
|
configureCiCd,
|
|
1757
1756
|
configureAutosync,
|
|
@@ -1861,7 +1860,7 @@ async function runInit(flags, options = {}) {
|
|
|
1861
1860
|
board ??= new InitProgressBoard;
|
|
1862
1861
|
return board;
|
|
1863
1862
|
};
|
|
1864
|
-
const validationFailure = () => new CliInputError("Moda Analyst produced a harness report that did not pass validation.", "Review .moda/harness-report-validation.json, then rerun `moda init --local --analyst=claude|cursor|codex` or `moda harness analyze --analyst=local-scan --summary`.");
|
|
1863
|
+
const validationFailure = () => new CliInputError("Moda Analyst produced a harness report that did not pass validation.", "Review .moda/harness-report-validation.json, then rerun `moda init --local --analyst=claude|cursor|codex` or `moda harness analyze --analyst=local-scan --summary --experimental`.");
|
|
1865
1864
|
let harnessPhase = { id: "harness", title: "Harness discovery", status: "completed" };
|
|
1866
1865
|
let harnessDeferred = false;
|
|
1867
1866
|
let harnessSkipped = false;
|
|
@@ -1891,7 +1890,7 @@ async function runInit(flags, options = {}) {
|
|
|
1891
1890
|
} : undefined;
|
|
1892
1891
|
if (signals && harnessLooksIncomplete(signals)) {
|
|
1893
1892
|
const names = [...signals.frameworks, ...signals.providers].join(", ");
|
|
1894
|
-
const retryCommand = remote ? "moda harness analyze --remote --summary --experimental" : "moda harness analyze --analyst=claude|cursor|codex --summary";
|
|
1893
|
+
const retryCommand = remote ? "moda harness analyze --remote --summary --experimental" : "moda harness analyze --analyst=claude|cursor|codex --summary --experimental";
|
|
1895
1894
|
warn(renderInitNote(`Harness discovery found 0 runtime agents, but this repo has LLM framework signals (${names}). ` + "Discovery likely failed, so the result was NOT approved or synced.", "warning"));
|
|
1896
1895
|
warn(` Retry with \`${retryCommand}\`, then \`moda harness approve --yes && moda harness sync --from-report\`.`);
|
|
1897
1896
|
emit("harness", "Harness discovery found 0 agents despite LLM framework signals; sync withheld.", "warning");
|
|
@@ -2012,7 +2011,6 @@ Harness analysis keeps running on Moda. Resume anytime with \`${HARNESS_PULL_REC
|
|
|
2012
2011
|
}
|
|
2013
2012
|
emit("apply", "Applying approved setup changes.");
|
|
2014
2013
|
const laneBoard = startBoard();
|
|
2015
|
-
const ingestCodingAgentTraces = false;
|
|
2016
2014
|
const agents = detectAgents();
|
|
2017
2015
|
laneBoard?.startLane("agent-skills", "Agent skills");
|
|
2018
2016
|
if (agents.length > 0) {
|
|
@@ -2093,7 +2091,6 @@ Harness analysis keeps running on Moda. Resume anytime with \`${HARNESS_PULL_REC
|
|
|
2093
2091
|
} else {
|
|
2094
2092
|
markApplied(setupPlan, "sdk", "User skipped SDK integration.");
|
|
2095
2093
|
}
|
|
2096
|
-
markApplied(setupPlan, "hooks", ingestCodingAgentTraces ? undefined : "Coding-agent trace capture is temporarily unavailable.");
|
|
2097
2094
|
markApplied(setupPlan, "prompts");
|
|
2098
2095
|
markApplied(setupPlan, "skills");
|
|
2099
2096
|
if (remote && pollPromise && remoteRunId) {
|
|
@@ -2214,16 +2211,7 @@ function buildSetupPlan(options) {
|
|
|
2214
2211
|
".moda/harness.json",
|
|
2215
2212
|
".moda/HARNESS.md"
|
|
2216
2213
|
],
|
|
2217
|
-
command: options.remote ? "moda harness analyze --remote --summary && moda harness approve --yes && moda harness sync --from-report" : "moda harness analyze --analyst=auto --summary && moda harness approve --yes && moda harness sync --from-report"
|
|
2218
|
-
},
|
|
2219
|
-
{
|
|
2220
|
-
category: "hooks",
|
|
2221
|
-
title: "Install coding-agent trace hooks",
|
|
2222
|
-
status: options.installHooks ? "planned" : "skipped",
|
|
2223
|
-
approved: options.installHooks,
|
|
2224
|
-
files: ["~/.claude/settings.json", "~/.codex/hooks.json", "~/.cursor/hooks.json"],
|
|
2225
|
-
command: "moda hooks install --agent=all",
|
|
2226
|
-
reason: options.installHooks ? undefined : "Coding-agent trace capture is temporarily unavailable."
|
|
2214
|
+
command: options.remote ? "moda harness analyze --remote --summary --experimental && moda harness approve --yes && moda harness sync --from-report" : "moda harness analyze --analyst=auto --summary --experimental && moda harness approve --yes && moda harness sync --from-report"
|
|
2227
2215
|
},
|
|
2228
2216
|
{
|
|
2229
2217
|
category: "prompts",
|
|
@@ -2274,7 +2262,7 @@ function buildSetupPlan(options) {
|
|
|
2274
2262
|
status: options.configureHarnessRescan ? "planned" : "manual",
|
|
2275
2263
|
approved: options.configureHarnessRescan,
|
|
2276
2264
|
files: [".github/workflows/moda-harness-rescan.yml"],
|
|
2277
|
-
command: "moda harness analyze --remote --yes && moda harness approve --yes && moda harness sync --from-report",
|
|
2265
|
+
command: "moda harness analyze --remote --yes --experimental && moda harness approve --yes && moda harness sync --from-report",
|
|
2278
2266
|
reason: options.configureHarnessRescan ? undefined : "No harness rescan workflow is written until it is explicitly approved (--harness-rescan)."
|
|
2279
2267
|
},
|
|
2280
2268
|
{
|
|
@@ -5,8 +5,8 @@ import {
|
|
|
5
5
|
inspectCodeSelectors,
|
|
6
6
|
inspectPythonSelectors,
|
|
7
7
|
safePromptEvidencePath
|
|
8
|
-
} from "./cli-
|
|
9
|
-
import"./cli-
|
|
8
|
+
} from "./cli-v27q5dvh.js";
|
|
9
|
+
import"./cli-0qnghzg4.js";
|
|
10
10
|
import {
|
|
11
11
|
__commonJS,
|
|
12
12
|
__toESM
|
|
@@ -9258,7 +9258,7 @@ class StdioServerTransport {
|
|
|
9258
9258
|
}
|
|
9259
9259
|
|
|
9260
9260
|
// src/prompt-analyst-tools.ts
|
|
9261
|
-
import {
|
|
9261
|
+
import { resolve } from "node:path";
|
|
9262
9262
|
function safeRoot(rootDir) {
|
|
9263
9263
|
const root = resolve(rootDir);
|
|
9264
9264
|
return root;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
selectTenantAndCreateKey
|
|
3
|
-
} from "./cli-
|
|
3
|
+
} from "./cli-7s48d6ty.js";
|
|
4
4
|
import {
|
|
5
5
|
loadAuthSession
|
|
6
|
-
} from "./cli-
|
|
6
|
+
} from "./cli-4f0p8erk.js";
|
|
7
7
|
import {
|
|
8
8
|
CliAuthError,
|
|
9
9
|
resolveIngestUrl,
|
|
10
10
|
resolveModaBaseUrl,
|
|
11
11
|
stringOption
|
|
12
|
-
} from "./cli-
|
|
12
|
+
} from "./cli-0qnghzg4.js";
|
|
13
13
|
import"./cli-0v6na3yp.js";
|
|
14
14
|
|
|
15
15
|
// src/provision.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moda-ai/cli",
|
|
3
|
-
"version": "1.55.
|
|
3
|
+
"version": "1.55.10",
|
|
4
4
|
"description": "CLI for Moda: production monitoring and evals for AI agents.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
"dist/**/*.js",
|
|
20
20
|
"dist/**/*.d.ts",
|
|
21
21
|
"!dist/__tests__",
|
|
22
|
-
"hooks/**",
|
|
23
22
|
"skills/**",
|
|
24
23
|
"README.md"
|
|
25
24
|
],
|
package/skills/moda-cli/SKILL.md
CHANGED
|
@@ -1291,8 +1291,8 @@ moda feedback "trace is a refund request, not this problem" \
|
|
|
1291
1291
|
you saw.
|
|
1292
1292
|
- Feedback does not change the problem itself. To act on a misroute directly,
|
|
1293
1293
|
use `moda problem-feedback <problem_id> --action=flag_attribution
|
|
1294
|
-
--attribution-id=<uuid> --reason=TEXT
|
|
1295
|
-
--reason=TEXT
|
|
1294
|
+
--attribution-id=<uuid> --reason=TEXT` or `moda false-positive <kind> <target>
|
|
1295
|
+
--reason=TEXT`.
|
|
1296
1296
|
- Never include secrets or full transcripts in the note.
|
|
1297
1297
|
|
|
1298
1298
|
## Validation — how to know it worked
|
package/hooks/moda-snapshot.sh
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# Moda shadow workspace hook for coding agents.
|
|
3
|
-
# Triggered by Claude Code, Codex, and Cursor lifecycle/tool matchers.
|
|
4
|
-
#
|
|
5
|
-
# Claude Code passes hook context as a JSON object on stdin (per the Claude
|
|
6
|
-
# Code hooks reference): session_id, tool_use_id, prompt, hook_event_name,
|
|
7
|
-
# etc. We forward that stdin straight through to `moda workspace snapshot
|
|
8
|
-
# --hook-stdin`, which parses it server-side so the CLI sees the same
|
|
9
|
-
# correlation keys (session_id, tool_use_id, prompt_sha) the ingest worker
|
|
10
|
-
# will later join on. The previous version read $CLAUDE_SESSION_ID and
|
|
11
|
-
# $CLAUDE_PROMPT_HASH env vars, but Claude never sets those — so session_id
|
|
12
|
-
# and prompt-level joins were unrecoverable. Reading stdin fixes that.
|
|
13
|
-
#
|
|
14
|
-
# Runs `moda workspace snapshot` in the background so the hook never blocks
|
|
15
|
-
# Claude; redirects all output to /dev/null so user-visible output stays
|
|
16
|
-
# clean; always exits 0 so a transient failure can't break the user session.
|
|
17
|
-
|
|
18
|
-
set +e
|
|
19
|
-
case "${1:-}" in
|
|
20
|
-
claude|claude_code|codex|cursor)
|
|
21
|
-
PROVIDER="$1"
|
|
22
|
-
EVENT="${2:-UserPromptSubmit}"
|
|
23
|
-
;;
|
|
24
|
-
*)
|
|
25
|
-
PROVIDER="claude_code"
|
|
26
|
-
EVENT="${1:-UserPromptSubmit}"
|
|
27
|
-
;;
|
|
28
|
-
esac
|
|
29
|
-
MODA_SNAPSHOT_BIN="${MODA_BIN:-moda}"
|
|
30
|
-
|
|
31
|
-
# Buffer the hook JSON once so the background subshell sees it after this
|
|
32
|
-
# script's stdin is closed by Claude.
|
|
33
|
-
PAYLOAD="$(cat)"
|
|
34
|
-
|
|
35
|
-
(
|
|
36
|
-
printf '%s' "$PAYLOAD" \
|
|
37
|
-
| "$MODA_SNAPSHOT_BIN" workspace snapshot --provider "$PROVIDER" --event "$EVENT" --json --hook-stdin \
|
|
38
|
-
> /dev/null 2>&1
|
|
39
|
-
) &
|
|
40
|
-
|
|
41
|
-
exit 0
|