@c4a/context-cli 0.6.6 → 0.6.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cli.js CHANGED
@@ -68955,12 +68955,22 @@ import { dirname as dirname22, join as join33, relative as relative13 } from "no
68955
68955
 
68956
68956
  // src/runtimeEvents.ts
68957
68957
  import { randomUUID as randomUUID2 } from "node:crypto";
68958
- import { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
68958
+ import {
68959
+ existsSync as existsSync8,
68960
+ mkdirSync,
68961
+ readFileSync as readFileSync4,
68962
+ renameSync,
68963
+ writeFileSync
68964
+ } from "node:fs";
68959
68965
  import { spawn as spawn2 } from "node:child_process";
68960
68966
  import { dirname as dirname15, join as join17 } from "node:path";
68961
68967
  import { fileURLToPath as fileURLToPath4 } from "node:url";
68962
68968
  var CONTEXT_RUNTIME_EVENT_BATCH_SCHEMA = "context.runtime-event-batch.v1";
68963
68969
  var CONTEXT_RUNTIME_EVENT_SINK_SCHEMA = "context.runtime-event-sink.v1";
68970
+ var CONTEXT_RUNTIME_EVENT_DELIVERY_TIMEOUT_MS = 3000;
68971
+ var CONTEXT_WORKSPACE_ACTIVE_THROTTLE_MS = 60 * 60 * 1000;
68972
+ var RUNTIME_EVENT_STATE_SCHEMA = "context.runtime-event-state.v1";
68973
+ var RUNTIME_EVENT_STATE_FILE = "runtime-event-state.json";
68964
68974
  var activeScope;
68965
68975
  function isRecord8(value) {
68966
68976
  return value !== null && typeof value === "object" && !Array.isArray(value);
@@ -69007,33 +69017,95 @@ function dispatchCommand(sink, batch, cwd) {
69007
69017
  return new Promise((resolve8) => {
69008
69018
  let settled = false;
69009
69019
  let timer;
69010
- const finish = () => {
69020
+ const finish = (delivered) => {
69011
69021
  if (settled)
69012
69022
  return;
69013
69023
  settled = true;
69014
69024
  if (timer !== undefined)
69015
69025
  clearTimeout(timer);
69016
- resolve8();
69026
+ resolve8(delivered);
69017
69027
  };
69018
69028
  try {
69019
69029
  const child = spawn2(sink.command, sink.args, {
69020
69030
  cwd,
69021
- detached: true,
69022
69031
  env: process.env,
69023
69032
  shell: false,
69024
69033
  stdio: ["pipe", "ignore", "ignore"]
69025
69034
  });
69026
- child.once("error", finish);
69027
- child.stdin.once("error", finish);
69028
- child.stdin.end(JSON.stringify(batch), finish);
69029
- child.unref();
69030
- timer = setTimeout(finish, 250);
69031
- timer.unref();
69035
+ child.once("error", () => finish(false));
69036
+ child.once("exit", (code) => finish(code === 0));
69037
+ child.stdin.once("error", () => {
69038
+ child.kill();
69039
+ finish(false);
69040
+ });
69041
+ child.stdin.end(JSON.stringify(batch));
69042
+ timer = setTimeout(() => {
69043
+ child.kill();
69044
+ finish(false);
69045
+ }, CONTEXT_RUNTIME_EVENT_DELIVERY_TIMEOUT_MS);
69032
69046
  } catch {
69033
- finish();
69047
+ finish(false);
69034
69048
  }
69035
69049
  });
69036
69050
  }
69051
+ function runtimeEventStatePath(cwd) {
69052
+ return join17(cwd, ".tmp", "context-runtime", RUNTIME_EVENT_STATE_FILE);
69053
+ }
69054
+ function readRuntimeEventState(cwd) {
69055
+ try {
69056
+ const parsed = JSON.parse(readFileSync4(runtimeEventStatePath(cwd), "utf8"));
69057
+ if (!isRecord8(parsed) || parsed.schema !== RUNTIME_EVENT_STATE_SCHEMA)
69058
+ return null;
69059
+ const active = parsed.workspace_active;
69060
+ if (active === undefined)
69061
+ return { schema: RUNTIME_EVENT_STATE_SCHEMA };
69062
+ if (!isRecord8(active) || typeof active.workflow_status !== "string" || typeof active.delivered_at !== "number" || !Number.isFinite(active.delivered_at)) {
69063
+ return null;
69064
+ }
69065
+ return {
69066
+ schema: RUNTIME_EVENT_STATE_SCHEMA,
69067
+ workspace_active: {
69068
+ workflow_status: active.workflow_status,
69069
+ delivered_at: active.delivered_at
69070
+ }
69071
+ };
69072
+ } catch {
69073
+ return null;
69074
+ }
69075
+ }
69076
+ function shouldDeliverWorkspaceActive(event, state) {
69077
+ const workflowStatus = event.properties.workflow_status;
69078
+ if (typeof workflowStatus !== "string")
69079
+ return true;
69080
+ const previous2 = state?.workspace_active;
69081
+ if (previous2 === undefined || previous2.workflow_status !== workflowStatus)
69082
+ return true;
69083
+ return event.event_time - previous2.delivered_at >= CONTEXT_WORKSPACE_ACTIVE_THROTTLE_MS;
69084
+ }
69085
+ function selectRuntimeEventsForDelivery(events, state) {
69086
+ return events.filter((event) => event.kind !== "workspace.active" || shouldDeliverWorkspaceActive(event, state));
69087
+ }
69088
+ function persistDeliveredWorkspaceActive(cwd, events) {
69089
+ const delivered = [...events].reverse().find((event) => event.kind === "workspace.active");
69090
+ const workflowStatus = delivered?.properties.workflow_status;
69091
+ if (delivered === undefined || typeof workflowStatus !== "string")
69092
+ return;
69093
+ try {
69094
+ const statePath = runtimeEventStatePath(cwd);
69095
+ const stateDir = dirname15(statePath);
69096
+ const temporaryPath = `${statePath}.${process.pid}.tmp`;
69097
+ mkdirSync(stateDir, { recursive: true });
69098
+ writeFileSync(temporaryPath, `${JSON.stringify({
69099
+ schema: RUNTIME_EVENT_STATE_SCHEMA,
69100
+ workspace_active: {
69101
+ workflow_status: workflowStatus,
69102
+ delivered_at: delivered.event_time
69103
+ }
69104
+ })}
69105
+ `, "utf8");
69106
+ renameSync(temporaryPath, statePath);
69107
+ } catch {}
69108
+ }
69037
69109
  async function flushRuntimeEvents(scope) {
69038
69110
  const grouped = new Map;
69039
69111
  for (const queued of scope.events) {
@@ -69043,11 +69115,18 @@ async function flushRuntimeEvents(scope) {
69043
69115
  }
69044
69116
  await Promise.all([...grouped.entries()].map(async ([cwd, events]) => {
69045
69117
  try {
69046
- await scope.dispatch(scope.sink, {
69047
- schema: CONTEXT_RUNTIME_EVENT_BATCH_SCHEMA,
69048
- context_version: scope.contextVersion,
69049
- events
69050
- }, cwd);
69118
+ const selectedEvents = selectRuntimeEventsForDelivery(events, readRuntimeEventState(cwd));
69119
+ if (selectedEvents.length === 0)
69120
+ return;
69121
+ try {
69122
+ await scope.dispatch(scope.sink, {
69123
+ schema: CONTEXT_RUNTIME_EVENT_BATCH_SCHEMA,
69124
+ context_version: scope.contextVersion,
69125
+ events: selectedEvents
69126
+ }, cwd);
69127
+ } finally {
69128
+ persistDeliveredWorkspaceActive(cwd, selectedEvents);
69129
+ }
69051
69130
  } catch {}
69052
69131
  }));
69053
69132
  }
@@ -69065,7 +69144,7 @@ function queueContextRuntimeEvent(input) {
69065
69144
  });
69066
69145
  }
69067
69146
  async function withContextRuntimeEventDelivery(work, options = {}) {
69068
- if (activeScope !== undefined || process.env.CONTEXT_RUNTIME_EVENTS_DISABLED === "1") {
69147
+ if (activeScope !== undefined || process.env.CONTEXT_RUNTIME_EVENTS_DISABLED === "1" && options.forceDelivery !== true) {
69069
69148
  return work();
69070
69149
  }
69071
69150
  const metadata = readRuntimePackageMetadata();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c4a/context-cli",
3
- "version": "0.6.6",
3
+ "version": "0.6.7",
4
4
  "type": "module",
5
5
  "description": "Local CLI for capturing, compiling, and governing knowledge workspaces",
6
6
  "license": "MIT",
@@ -24,7 +24,7 @@
24
24
  },
25
25
  "dependencies": {
26
26
  "@c4a/agent-graph": "0.2.5",
27
- "@c4a/context": "0.6.6",
27
+ "@c4a/context": "0.6.7",
28
28
  "commander": "^11.0.0",
29
29
  "fast-xml-parser": "^5.10.1",
30
30
  "handlebars": "^4.7.8",
package/plugins/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.6
1
+ 0.6.7
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "context",
3
3
  "description": "Maintain a project-local knowledge workspace through init and next-step agent guidance.",
4
- "version": "0.6.6",
4
+ "version": "0.6.7",
5
5
  "author": {
6
6
  "name": "c4a"
7
7
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "context",
3
- "version": "0.6.6",
3
+ "version": "0.6.7",
4
4
  "description": "Maintain a project-local knowledge workspace through init and next-step agent guidance.",
5
5
  "author": {
6
6
  "name": "c4a"
@@ -18,7 +18,7 @@
18
18
  "skills": "./skills/",
19
19
  "interface": {
20
20
  "displayName": "C4A Context",
21
- "shortDescription": "Initialize and advance a local, source-linked project knowledge workspace.\nv0.6.6",
21
+ "shortDescription": "Initialize and advance a local, source-linked project knowledge workspace.\nv0.6.7",
22
22
  "longDescription": "Create a Context workspace and use agent-guided next steps to register sources, run extraction, review candidates, build package outputs, and verify health without silently mutating source repositories.",
23
23
  "developerName": "c4a",
24
24
  "category": "Productivity",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "context",
3
3
  "displayName": "C4A Context",
4
- "version": "0.6.6",
4
+ "version": "0.6.7",
5
5
  "description": "Maintain a project-local knowledge workspace through init and next-step agent guidance.",
6
6
  "author": {
7
7
  "name": "Context4AI",
@@ -2,7 +2,7 @@
2
2
  "schema": "agent-graph.bundle.v1",
3
3
  "provider": {
4
4
  "id": "c4a/context",
5
- "version": "0.6.6"
5
+ "version": "0.6.7"
6
6
  },
7
7
  "providerManifest": "provider.yaml",
8
8
  "graphs": [
@@ -508,7 +508,7 @@
508
508
  },
509
509
  {
510
510
  "path": "provider.yaml",
511
- "digest": "sha256:d13207554b08b390963585983ee0a931811d787f070e0e041d6881bc929950ee"
511
+ "digest": "sha256:ba20dd22b84639677e224787555f427e66042a72101454824e136bca222034da"
512
512
  },
513
513
  {
514
514
  "path": "resources/diagnostics/projection-stale.md",
@@ -714,5 +714,5 @@
714
714
  "graphDependencies": {
715
715
  "workspace": []
716
716
  },
717
- "digest": "sha256:9e18f9627b218543ae2bcbcdf3a98204c7d84d7078738b1af39f35d3a6047795"
717
+ "digest": "sha256:9e3ccfd59436360fd799f8f399c848caa7b52a51e50c61562d1aa3c06f905dae"
718
718
  }
@@ -1,6 +1,6 @@
1
1
  schema: agent-graph.provider.v1
2
2
  id: c4a/context
3
- version: 0.6.6
3
+ version: 0.6.7
4
4
  name: Context workflow
5
5
  description: Internal work contract for Context knowledge workspaces.
6
6
  graphs: