@ascenda-one/agent-mcp 0.1.17 → 0.1.19

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.
Files changed (2) hide show
  1. package/dist/cli.js +93 -10
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -587,7 +587,61 @@ var require_out = __commonJS({
587
587
  "../packages/tool-contract/out/index.js"(exports) {
588
588
  "use strict";
589
589
  Object.defineProperty(exports, "__esModule", { value: true });
590
- exports.backendMetricKeys = exports.METRIC_KEYS = exports.ASCENDA_SEMANTIC_PROVENANCE = exports.ASCENDA_HISTORICAL_CONSENT_SCOPE = exports.ASCENDA_COLLABORATION_CONSENT_SCOPE = exports.ASCENDA_SEMANTIC_CONSENT_SCOPE = exports.ASCENDA_PROVENANCE = exports.ASCENDA_CONSENT_SCOPE = exports.EVENT_WORKLOAD_CATEGORY = exports.TOOL_EVENT_DELIVERED_STATUSES = exports.IDEMPOTENCY_KEY_MAX_LENGTH = exports.EVENT_METADATA_FIELDS = exports.COLLABORATION_EVENT_TYPES = exports.SEMANTIC_WORK_SIGNAL_EVENT_TYPES = void 0;
590
+ exports.backendMetricKeys = exports.METRIC_KEYS = exports.ASCENDA_SEMANTIC_PROVENANCE = exports.ASCENDA_HISTORICAL_CONSENT_SCOPE = exports.ASCENDA_COLLABORATION_CONSENT_SCOPE = exports.ASCENDA_SEMANTIC_CONSENT_SCOPE = exports.ASCENDA_PROVENANCE = exports.ASCENDA_CONSENT_SCOPE = exports.EVENT_WORKLOAD_CATEGORY = exports.TOOL_EVENT_DELIVERED_STATUSES = exports.IDEMPOTENCY_KEY_MAX_LENGTH = exports.EVENT_METADATA_FIELDS = exports.COLLABORATION_EVENT_TYPES = exports.SEMANTIC_WORK_SIGNAL_EVENT_TYPES = exports.ASCENDA_ELAPSED_QUANTITIES = exports.ASCENDA_ACTIVE_TIME_QUANTITIES = exports.ASCENDA_TOOL_TYPES = exports.ASCENDA_TELEMETRY_SOURCES = void 0;
591
+ exports.combineDisjointHalves = combineDisjointHalves;
592
+ exports.requireComparableQuantities = requireComparableQuantities;
593
+ exports.ASCENDA_TELEMETRY_SOURCES = [
594
+ "vscode_extension",
595
+ "cursor_mcp",
596
+ "claude_code",
597
+ "copilot_otel",
598
+ "cli_agent",
599
+ "mcp_server",
600
+ "activity_signals",
601
+ "code_forge"
602
+ ];
603
+ exports.ASCENDA_TOOL_TYPES = [
604
+ "vscode_extension",
605
+ "cursor_mcp",
606
+ "claude_code",
607
+ "copilot_otel",
608
+ "cli_agent",
609
+ "mcp_server",
610
+ "github_collector",
611
+ "other"
612
+ ];
613
+ exports.ASCENDA_ACTIVE_TIME_QUANTITIES = [
614
+ "coverage",
615
+ "hands_on",
616
+ "supervising",
617
+ "block_coverage",
618
+ "hands_on_agent_hours",
619
+ "supervising_agent_hours"
620
+ ];
621
+ exports.ASCENDA_ELAPSED_QUANTITIES = {
622
+ coverage: true,
623
+ hands_on: true,
624
+ supervising: true,
625
+ block_coverage: true,
626
+ hands_on_agent_hours: false,
627
+ supervising_agent_hours: false
628
+ };
629
+ var DISJOINT_HALVES = [
630
+ ["hands_on", "supervising", "coverage"],
631
+ ["supervising", "hands_on", "coverage"]
632
+ ];
633
+ function combineDisjointHalves(left, leftQuantity, right, rightQuantity) {
634
+ const pair = DISJOINT_HALVES.find(([a, b]) => a === leftQuantity && b === rightQuantity);
635
+ if (!pair) {
636
+ throw new Error(`'combine-disjoint' combines active-time quantities '${leftQuantity}' and '${rightQuantity}', which do not partition a common whole.`);
637
+ }
638
+ return { total: left + right, quantity: pair[2] };
639
+ }
640
+ function requireComparableQuantities(left, right, operation) {
641
+ if (left !== right) {
642
+ throw new Error(`'${operation}' combines active-time quantities '${left}' and '${right}', which measure different things. See docs/ACTIVE_TIME.md, 'The quantity is the label, not the gap'.`);
643
+ }
644
+ }
591
645
  exports.SEMANTIC_WORK_SIGNAL_EVENT_TYPES = [
592
646
  "approach_churn_detected",
593
647
  "goal_drift_detected",
@@ -1171,12 +1225,11 @@ var require_stateStore = __commonJS({
1171
1225
  exports.shouldAnnounceFailure = shouldAnnounceFailure;
1172
1226
  exports.markFailureNotified = markFailureNotified;
1173
1227
  var fs = __importStar(__require("fs"));
1174
- var os = __importStar(__require("os"));
1175
1228
  var path = __importStar(__require("path"));
1176
1229
  var tokenStore_1 = require_tokenStore();
1177
1230
  function defaultStateFilePath(toolInstallationId) {
1178
1231
  const dir = process.env.ASCENDA_STATE_DIR?.trim();
1179
- const base = dir ? dir : path.join(os.homedir(), ".ascenda", "state");
1232
+ const base = dir ? dir : path.join((0, tokenStore_1.ascendaHome)(), "state");
1180
1233
  return path.join(base, `${(0, tokenStore_1.sanitizeFilePart)(toolInstallationId)}.json`);
1181
1234
  }
1182
1235
  function unresolvedToolInstallationId(toolType) {
@@ -1498,6 +1551,25 @@ var require_outbox = __commonJS({
1498
1551
  }
1499
1552
  });
1500
1553
 
1554
+ // ../packages/tool-kit/out/timeProvider.js
1555
+ var require_timeProvider = __commonJS({
1556
+ "../packages/tool-kit/out/timeProvider.js"(exports) {
1557
+ "use strict";
1558
+ Object.defineProperty(exports, "__esModule", { value: true });
1559
+ exports.systemTimeProvider = void 0;
1560
+ exports.fixedTimeProvider = fixedTimeProvider;
1561
+ exports.systemTimeProvider = {
1562
+ now: () => Date.now()
1563
+ };
1564
+ function fixedTimeProvider(instant) {
1565
+ const ms = typeof instant === "number" ? instant : new Date(instant).valueOf();
1566
+ if (!Number.isFinite(ms))
1567
+ throw new TypeError(`fixedTimeProvider: not a usable instant: ${String(instant)}`);
1568
+ return { now: () => ms };
1569
+ }
1570
+ }
1571
+ });
1572
+
1501
1573
  // ../packages/tool-kit/out/eventSender.js
1502
1574
  var require_eventSender = __commonJS({
1503
1575
  "../packages/tool-kit/out/eventSender.js"(exports) {
@@ -1510,6 +1582,7 @@ var require_eventSender = __commonJS({
1510
1582
  var eventLog_1 = require_eventLog();
1511
1583
  var http_1 = require_http();
1512
1584
  var outbox_1 = require_outbox();
1585
+ var timeProvider_1 = require_timeProvider();
1513
1586
  var tokenStore_1 = require_tokenStore();
1514
1587
  var stateStore_1 = require_stateStore();
1515
1588
  var payload_1 = require_payload();
@@ -1546,9 +1619,12 @@ var require_eventSender = __commonJS({
1546
1619
  lastDrain;
1547
1620
  /** One outbox pass per sender, i.e. per hook process. The hook is on the user's critical path. */
1548
1621
  outboxServiced = false;
1622
+ /** Resolved once, so every clock read in one pass sees the same instant. */
1623
+ time;
1549
1624
  constructor(config2) {
1550
1625
  this.config = config2;
1551
1626
  this.eventWriteToken = config2.eventWriteToken;
1627
+ this.time = config2.timeProvider ?? timeProvider_1.systemTimeProvider;
1552
1628
  }
1553
1629
  async send(mapped) {
1554
1630
  return this.post(buildEventPayload(this.config, mapped));
@@ -1699,7 +1775,7 @@ var require_eventSender = __commonJS({
1699
1775
  * journal's detail says so instead of implying it was kept.
1700
1776
  */
1701
1777
  enqueue(payload) {
1702
- return (0, outbox_1.appendToOutbox)(this.outboxFilePath(), payload);
1778
+ return (0, outbox_1.appendToOutbox)(this.outboxFilePath(), payload, new Date(this.time.now()));
1703
1779
  }
1704
1780
  /**
1705
1781
  * One pass over the outbox: claim it, apply the bounds, and — when sending
@@ -1722,7 +1798,7 @@ var require_eventSender = __commonJS({
1722
1798
  return void 0;
1723
1799
  this.outboxServiced = true;
1724
1800
  const sendEnabled = this.config.outboxDrain ?? (0, outbox_1.outboxDrainEnabled)();
1725
- const claimed = (0, outbox_1.claimOutbox)(this.outboxFilePath());
1801
+ const claimed = (0, outbox_1.claimOutbox)(this.outboxFilePath(), this.time.now());
1726
1802
  if (!claimed) {
1727
1803
  this.lastDrain = { found: 0, discarded: 0, delivered: 0, remaining: 0, sendEnabled };
1728
1804
  return void 0;
@@ -1731,7 +1807,7 @@ var require_eventSender = __commonJS({
1731
1807
  const { kept, discarded } = (0, outbox_1.enforceOutboxBounds)(claimed.entries, {
1732
1808
  maxEntries: this.config.outboxMaxEntries ?? outbox_1.DEFAULT_OUTBOX_MAX_ENTRIES,
1733
1809
  maxAgeMs: this.config.outboxMaxAgeMs ?? outbox_1.DEFAULT_OUTBOX_MAX_AGE_MS
1734
- });
1810
+ }, this.time.now());
1735
1811
  if (claimed.unreadable > 0) {
1736
1812
  discarded.count += claimed.unreadable;
1737
1813
  discarded.reasons.unreadable = claimed.unreadable;
@@ -3153,9 +3229,9 @@ var require_turnState = __commonJS({
3153
3229
  exports.recordTurnStart = recordTurnStart;
3154
3230
  exports.consumeTurnDurationMs = consumeTurnDurationMs;
3155
3231
  var fs = __importStar(__require("fs"));
3156
- var os = __importStar(__require("os"));
3157
3232
  var path = __importStar(__require("path"));
3158
- var stateDir = () => process.env.ASCENDA_STATE_DIR ?? path.join(os.homedir(), ".ascenda", "state");
3233
+ var tokenStore_1 = require_tokenStore();
3234
+ var stateDir = () => process.env.ASCENDA_STATE_DIR ?? path.join((0, tokenStore_1.ascendaHome)(), "state");
3159
3235
  function turnFile(agent, sessionId) {
3160
3236
  return path.join(stateDir(), `${sanitize(agent)}-turn-${sanitize(sessionId)}`);
3161
3237
  }
@@ -3322,8 +3398,8 @@ var require_out2 = __commonJS({
3322
3398
  "use strict";
3323
3399
  Object.defineProperty(exports, "__esModule", { value: true });
3324
3400
  exports.consumeTurnDurationMs = exports.writeTopLevelCredentials = exports.writeMachineCredentials = exports.writeHostCredentials = exports.removeHostCredentials = exports.readMachineCredentials = exports.readHostCredentials = exports.credentialsFilePath = exports.writeHookSettings = exports.runCliAgentSetup = exports.isCliAgentManagementCommand = exports.findStaleHookCommands = exports.cliAgentHookBinPath = exports.resolveContextHashes = exports.resolveCliAgentInstallationId = exports.loadCliAgentConfig = exports.deliverHookEvents = exports.MissingInstallationIdError = exports.DEFAULT_API_BASE_URL = exports.resolveEventLogPath = exports.expandUserPath = exports.appendEventLog = exports.EVENT_LOG_ENV_VAR = exports.buildEventPayload = exports.AscendaSemanticEventError = exports.AscendaEventSender = exports.mintIdempotencyKey = exports.looksLikeCorrection = exports.outcomeForHook = exports.inferOutcome = exports.getNestedNumber = exports.getNestedString = exports.getNested = exports.getNumber = exports.getString = exports.localHourAt = exports.utcOffsetMinutesAt = exports.BUSINESS_DAY = exports.isOutsideBusinessHours = exports.isAfterHours = exports.bucketDurationMs = exports.bucketLinesChanged = exports.classifyModelClass = exports.autonomyBand = exports.invitesDebrief = exports.classifyWorkMilestone = exports.isReworkGitAction = exports.classifyGitAction = exports.isVerificationCommand = exports.classifyCommand = void 0;
3325
- exports.postToolEvent = exports.renewToolToken = exports.getPairingStatus = exports.createPairingSession = exports.AscendaApiError = exports.liveBusSocketCandidates = exports.liveBusSocketPath = exports.bucketPromptSize = exports.emitLiveSignal = exports.recordForgeProjectAlias = exports.forgeFullNameFromConfig = exports.readForgeFullName = exports.parseForgeFullName = exports.forgeProjectHash = exports.workContextRegistryFilePath = exports.readWorkContextRegistry = exports.recordWorkContextAlias = exports.recordWorkContext = exports.readBranchName = exports.normalizeBranchName = exports.deriveBranchHashForCwd = exports.deriveBranchHash = exports.deriveWorkContext = exports.hashWithMachineSalt = exports.readOrCreateMachineSalt = exports.machineSaltFilePath = exports.enforceOutboxBounds = exports.claimOutbox = exports.readOutboxSummary = exports.appendToOutbox = exports.defaultOutboxFilePath = exports.outboxDrainEnabled = exports.DEFAULT_OUTBOX_DRAIN_BATCH_SIZE = exports.DEFAULT_OUTBOX_MAX_AGE_MS = exports.DEFAULT_OUTBOX_MAX_ENTRIES = exports.OUTBOX_DRAIN_ENV_VAR = exports.recordOutboxDiscard = exports.unresolvedToolInstallationId = exports.unresolvedStateFilePath = exports.markFailureNotified = exports.shouldAnnounceFailure = exports.recordSendOutcome = exports.readCollectorState = exports.defaultStateFilePath = exports.readTokenFile = exports.persistEventWriteToken = exports.listPersistedToolInstallationIds = exports.defaultTokenFilePath = exports.ascendaHome = exports.recordTurnStart = void 0;
3326
- exports.isRetryableStatus = exports.parseIngestResponse = exports.postToolEventsBatch = void 0;
3401
+ exports.getPairingStatus = exports.createPairingSession = exports.AscendaApiError = exports.liveBusSocketCandidates = exports.liveBusSocketPath = exports.bucketPromptSize = exports.emitLiveSignal = exports.recordForgeProjectAlias = exports.forgeFullNameFromConfig = exports.readForgeFullName = exports.parseForgeFullName = exports.forgeProjectHash = exports.workContextRegistryFilePath = exports.readWorkContextRegistry = exports.recordWorkContextAlias = exports.recordWorkContext = exports.readBranchName = exports.normalizeBranchName = exports.deriveBranchHashForCwd = exports.deriveBranchHash = exports.deriveWorkContext = exports.hashWithMachineSalt = exports.readOrCreateMachineSalt = exports.machineSaltFilePath = exports.fixedTimeProvider = exports.systemTimeProvider = exports.enforceOutboxBounds = exports.claimOutbox = exports.readOutboxSummary = exports.appendToOutbox = exports.defaultOutboxFilePath = exports.outboxDrainEnabled = exports.DEFAULT_OUTBOX_DRAIN_BATCH_SIZE = exports.DEFAULT_OUTBOX_MAX_AGE_MS = exports.DEFAULT_OUTBOX_MAX_ENTRIES = exports.OUTBOX_DRAIN_ENV_VAR = exports.recordOutboxDiscard = exports.unresolvedToolInstallationId = exports.unresolvedStateFilePath = exports.markFailureNotified = exports.shouldAnnounceFailure = exports.recordSendOutcome = exports.readCollectorState = exports.defaultStateFilePath = exports.readTokenFile = exports.persistEventWriteToken = exports.listPersistedToolInstallationIds = exports.defaultTokenFilePath = exports.ascendaHome = exports.recordTurnStart = void 0;
3402
+ exports.isRetryableStatus = exports.parseIngestResponse = exports.postToolEventsBatch = exports.postToolEvent = exports.renewToolToken = void 0;
3327
3403
  var commandClassifier_1 = require_commandClassifier();
3328
3404
  Object.defineProperty(exports, "classifyCommand", { enumerable: true, get: function() {
3329
3405
  return commandClassifier_1.classifyCommand;
@@ -3563,6 +3639,13 @@ var require_out2 = __commonJS({
3563
3639
  Object.defineProperty(exports, "enforceOutboxBounds", { enumerable: true, get: function() {
3564
3640
  return outbox_1.enforceOutboxBounds;
3565
3641
  } });
3642
+ var timeProvider_1 = require_timeProvider();
3643
+ Object.defineProperty(exports, "systemTimeProvider", { enumerable: true, get: function() {
3644
+ return timeProvider_1.systemTimeProvider;
3645
+ } });
3646
+ Object.defineProperty(exports, "fixedTimeProvider", { enumerable: true, get: function() {
3647
+ return timeProvider_1.fixedTimeProvider;
3648
+ } });
3566
3649
  var salt_1 = require_salt();
3567
3650
  Object.defineProperty(exports, "machineSaltFilePath", { enumerable: true, get: function() {
3568
3651
  return salt_1.machineSaltFilePath;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "publishConfig": { "access": "public" },
3
3
  "name": "@ascenda-one/agent-mcp",
4
- "version": "0.1.17",
4
+ "version": "0.1.19",
5
5
  "description": "MCP server exposing ascenda_emit_work_signal — the one submission interface for agent-observed (semantic) work-friction signals.",
6
6
  "repository": {
7
7
  "type": "git",