@hham21/circe 0.4.0 → 0.5.0

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.

Potentially problematic release.


This version of @hham21/circe might be problematic. Click here for more details.

package/README.md CHANGED
@@ -7,60 +7,46 @@ Inspired by Anthropic's [Harness Design for Long-Running Application Development
7
7
  ## Install
8
8
 
9
9
  ```bash
10
- git clone https://github.com/hham21/circe.git
11
- cd circe
12
- npm install
10
+ npm install @hham21/circe
13
11
  ```
14
12
 
15
- Requires Node.js 22+ and [Claude Code](https://claude.ai/code) authenticated via OAuth or API key:
13
+ Requires Node.js 22+ and a Claude API key:
16
14
 
17
15
  ```bash
18
16
  export ANTHROPIC_API_KEY=sk-ant-...
19
17
  ```
20
18
 
21
- Run examples with `npx tsx` (see [examples/README.md](examples/README.md) for the full list):
22
-
23
- ```bash
24
- npx tsx examples/01-single-agent.ts
25
- npx tsx examples/06-compose.ts # the money shot — nested primitives
26
- ```
27
-
28
19
  ## Quick Start
29
20
 
30
21
  ```typescript
31
- import { Pipeline, Loop, agent } from "circe";
22
+ import { Agent, Loop, Session } from "@hham21/circe";
32
23
 
33
- const planner = agent({
34
- name: "planner",
35
- prompt: "Expand the user prompt into a detailed product spec.",
36
- });
37
-
38
- const generator = agent({
24
+ const generator = new Agent({
39
25
  name: "generator",
40
26
  prompt: "Build the app based on the spec or QA feedback.",
27
+ model: "claude-sonnet-4-6",
41
28
  });
42
29
 
43
- const evaluator = agent({
30
+ const evaluator = new Agent({
44
31
  name: "evaluator",
45
- prompt: "Test the app with Playwright. FAIL with feedback if issues found.",
46
- tools: ["Read", "Bash", "Glob", "Grep"],
47
- skills: ["qa", "browse"],
32
+ prompt: "Test the app. FAIL with feedback if issues found.",
33
+ model: "claude-opus-4-6",
48
34
  });
49
35
 
50
- const app = new Pipeline(
51
- planner,
52
- new Loop(generator, evaluator, { maxRounds: 3, stopWhen: (r: any) => r.passed }),
53
- );
36
+ const loop = new Loop(generator, evaluator, { maxRounds: 3 });
54
37
 
55
- await app.run("Build a retro game maker");
38
+ await new Session({ outputDir: "./output", verbose: true })
39
+ .run(() => loop.run("Build a retro game maker"));
56
40
  ```
57
41
 
42
+ See [examples/](examples/README.md) for 14 progressive examples (`npx tsx examples/01-single-agent.ts`).
43
+
58
44
  ## Concepts
59
45
 
60
46
  ### Agents
61
47
 
62
48
  ```typescript
63
- import { Agent, agent } from "circe";
49
+ import { Agent, agent } from "@hham21/circe";
64
50
 
65
51
  // Factory function (simple)
66
52
  const reviewer = agent({
@@ -73,13 +59,14 @@ const reviewer = agent({
73
59
  const evaluator = new Agent({
74
60
  name: "evaluator",
75
61
  prompt: "Strict QA engineer.",
62
+ model: "claude-opus-4-6",
76
63
  tools: ["Read", "Bash"],
77
64
  skills: ["qa"],
78
65
  contextStrategy: "reset",
79
66
  });
80
67
  ```
81
68
 
82
- All Claude Agent SDK built-in tools (Read, Write, Edit, Bash, Glob, Grep, WebSearch, WebFetch, Agent) are available by default. Restrict with `tools`.
69
+ All Claude Agent SDK built-in tools (Read, Write, Edit, Bash, Glob, Grep, WebSearch, WebFetch, Agent) are available by default. Restrict with `tools`. Set `model` per agent to control cost/capability.
83
70
 
84
71
  ### Orchestrators
85
72
 
@@ -98,7 +85,7 @@ Loop and Contract return **producer output on success** (the content, not the ev
98
85
  Compose freely:
99
86
 
100
87
  ```typescript
101
- import { pipe } from "circe";
88
+ import { pipe } from "@hham21/circe";
102
89
 
103
90
  // Type-safe pipeline — compiler checks that output types chain correctly
104
91
  pipe(planner, new Loop(generator, evaluator, { maxRounds: 3 }));
@@ -107,10 +94,25 @@ pipe(planner, new Loop(generator, evaluator, { maxRounds: 3 }));
107
94
  pipe(planner, new Contract(proposer, reviewer), new Loop(generator, evaluator));
108
95
  ```
109
96
 
97
+ ### Session
98
+
99
+ Session eliminates boilerplate. It auto-creates the output directory, sets up logging, initializes the skill registry, and cleans up when done. Context propagates through any orchestrator nesting via `AsyncLocalStorage`.
100
+
101
+ ```typescript
102
+ import { Session } from "@hham21/circe";
103
+
104
+ const session = new Session({ outputDir: "./output/my-app", verbose: true });
105
+ await session.run(() => pipeline.run("Build a todo app"));
106
+
107
+ console.log(`Duration: ${session.duration.toFixed(1)}s`);
108
+ ```
109
+
110
+ Without Session, you can still use the global setters (`setFormatter`, `setWorkDir`, `setSkillRegistry`) directly.
111
+
110
112
  ### Tools
111
113
 
112
114
  ```typescript
113
- import { tool } from "circe";
115
+ import { tool } from "@hham21/circe";
114
116
 
115
117
  const searchNpm = tool(function searchNpm(query: string): string {
116
118
  // Search npm packages
@@ -128,7 +130,7 @@ Skills are on-demand prompt templates. Agents load them when needed:
128
130
  const evaluator = agent({
129
131
  name: "evaluator",
130
132
  prompt: "QA engineer.",
131
- skills: ["qa", "browse"],
133
+ skills: ["qa"],
132
134
  });
133
135
  ```
134
136
 
@@ -153,24 +155,19 @@ Zod schemas for structured agent-to-agent data passing:
153
155
 
154
156
  ```bash
155
157
  # Run a workflow file
156
- circe run workflow.js -i "prompt or spec file"
157
-
158
- # Agent management
159
- circe agents create my-reviewer --prompt "Review code." --tools "Read,Grep"
160
- circe agents list
161
- circe agents info my-reviewer
162
- circe agents delete my-reviewer
163
-
164
- # Workflow management
165
- circe workflows create my-pipe --agents "planner,generator,evaluator"
166
- circe workflows list
167
- circe workflows delete my-pipe
158
+ circe run workflow.js -i "prompt or spec file" -v
159
+
160
+ # Skill management
161
+ circe skills list
162
+ circe skills create my-skill
163
+ circe skills info my-skill
168
164
  ```
169
165
 
170
166
  ## Architecture
171
167
 
172
168
  ```
173
- CLI Layer circe run, agents, workflows
169
+ Session Layer Session (AsyncLocalStorage context propagation)
170
+ CLI Layer circe run, skills
174
171
  Orchestration Pipeline, Loop, Parallel, Sprint, Contract
175
172
  Agent Layer Agent, agent(), Handoff, Context Strategy
176
173
  Tool Layer SDK built-ins, tool(), MCP servers, Skills
package/circe.log ADDED
File without changes
package/dist/cli/index.js CHANGED
@@ -12,14 +12,12 @@ program
12
12
  .description("Run a workflow file")
13
13
  .requiredOption("-i, --input <input>", "User input or path to spec file")
14
14
  .option("-o, --output <dir>", "Output directory")
15
- .option("-r, --max-rounds <n>", "Maximum rounds", parseInt)
16
15
  .option("-v, --verbose", "Verbose output")
17
16
  .action(async (workflow, opts) => {
18
17
  await executeWorkflow({
19
18
  workflow,
20
19
  input: opts.input,
21
20
  outputDir: opts.output,
22
- maxRounds: opts.maxRounds,
23
21
  verbose: opts.verbose,
24
22
  });
25
23
  });
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAShD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,OAAO,CAAC;KACb,WAAW,CAAC,4DAA4D,CAAC;KACzE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,gBAAgB,CAAC;KACzB,WAAW,CAAC,qBAAqB,CAAC;KAClC,cAAc,CAAC,qBAAqB,EAAE,iCAAiC,CAAC;KACxE,MAAM,CAAC,oBAAoB,EAAE,kBAAkB,CAAC;KAChD,MAAM,CAAC,sBAAsB,EAAE,gBAAgB,EAAE,QAAQ,CAAC;KAC1D,MAAM,CAAC,eAAe,EAAE,gBAAgB,CAAC;KACzC,MAAM,CAAC,KAAK,EAAE,QAAgB,EAAE,IAAgB,EAAE,EAAE;IACnD,MAAM,eAAe,CAAC;QACpB,QAAQ;QACR,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,SAAS,EAAE,IAAI,CAAC,MAAM;QACtB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,OAAO,EAAE,IAAI,CAAC,OAAO;KACtB,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAElC,OAAO,EAAE,OAAO,EAAE,CAAC;AAEnB,OAAO,CAAC,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAQhD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,OAAO,CAAC;KACb,WAAW,CAAC,4DAA4D,CAAC;KACzE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,gBAAgB,CAAC;KACzB,WAAW,CAAC,qBAAqB,CAAC;KAClC,cAAc,CAAC,qBAAqB,EAAE,iCAAiC,CAAC;KACxE,MAAM,CAAC,oBAAoB,EAAE,kBAAkB,CAAC;KAChD,MAAM,CAAC,eAAe,EAAE,gBAAgB,CAAC;KACzC,MAAM,CAAC,KAAK,EAAE,QAAgB,EAAE,IAAgB,EAAE,EAAE;IACnD,MAAM,eAAe,CAAC;QACpB,QAAQ;QACR,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,SAAS,EAAE,IAAI,CAAC,MAAM;QACtB,OAAO,EAAE,IAAI,CAAC,OAAO;KACtB,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAElC,OAAO,EAAE,OAAO,EAAE,CAAC;AAEnB,OAAO,CAAC,KAAK,EAAE,CAAC"}
package/dist/cli/run.d.ts CHANGED
@@ -2,7 +2,6 @@ export declare function executeWorkflow(options: {
2
2
  workflow: string;
3
3
  input: string;
4
4
  outputDir?: string;
5
- maxRounds?: number;
6
5
  verbose?: boolean;
7
6
  }): Promise<void>;
8
7
  export declare function slugify(text: string): string;
package/dist/cli/run.js CHANGED
@@ -1,26 +1,24 @@
1
- import { existsSync, readFileSync, mkdirSync } from "node:fs";
1
+ import { existsSync, readFileSync } from "node:fs";
2
2
  import { join, resolve } from "node:path";
3
- import { OutputFormatter } from "./output.js";
4
- import { setFormatter, setWorkDir, setSkillRegistry } from "../context.js";
5
- import { SkillRegistry } from "../tools/skills.js";
3
+ import { Session } from "../session.js";
6
4
  const SLUG_MAX_LENGTH = 50;
7
5
  export async function executeWorkflow(options) {
8
- const { workflow, input: rawInput, outputDir, maxRounds, verbose } = options;
6
+ const { workflow, input: rawInput, outputDir, verbose } = options;
9
7
  const userInput = resolveInput(rawInput);
10
- const workDir = resolveWorkDir(userInput, outputDir);
11
- const formatter = initializeContext(workDir, verbose);
12
- const startTime = Date.now();
13
- try {
14
- const runner = await loadWorkflowFile(workflow);
15
- const result = await runner.run(userInput);
16
- formatter.logResult(serializeResult(result));
17
- }
18
- finally {
19
- const elapsedSeconds = (Date.now() - startTime) / 1000;
20
- formatter.finalSummary(workDir, elapsedSeconds);
21
- formatter.close();
22
- teardownContext();
23
- }
8
+ const slug = slugify(userInput);
9
+ const baseOutput = outputDir ?? resolve("output");
10
+ const outDir = findUniqueOutputDir(baseOutput, slug);
11
+ const session = new Session({ outputDir: outDir, verbose });
12
+ await session.run(async () => {
13
+ try {
14
+ const runner = await loadWorkflowFile(workflow);
15
+ const result = await runner.run(userInput);
16
+ session.formatter.logResult(serializeResult(result));
17
+ }
18
+ finally {
19
+ session.formatter.finalSummary(outDir, session.duration);
20
+ }
21
+ });
24
22
  }
25
23
  export function slugify(text) {
26
24
  return text
@@ -47,33 +45,6 @@ export function findUniqueOutputDir(base, slug) {
47
45
  }
48
46
  return join(base, `${slug}-${counter}`);
49
47
  }
50
- function resolveWorkDir(userInput, outputDir) {
51
- const slug = slugify(userInput);
52
- const baseOutput = outputDir ?? resolve("output");
53
- const workDir = findUniqueOutputDir(baseOutput, slug);
54
- mkdirSync(workDir, { recursive: true });
55
- return workDir;
56
- }
57
- function initializeContext(workDir, verbose) {
58
- const formatter = new OutputFormatter(verbose);
59
- formatter.setLogFile(join(workDir, "circe.log"));
60
- setFormatter(formatter);
61
- setWorkDir(workDir);
62
- setSkillRegistry(createSkillRegistry(workDir));
63
- return formatter;
64
- }
65
- function createSkillRegistry(workDir) {
66
- const skillDirs = [
67
- join(workDir, ".circe", "skills"),
68
- join(process.env.HOME, ".circe", "skills"),
69
- ];
70
- return new SkillRegistry(skillDirs);
71
- }
72
- function teardownContext() {
73
- setFormatter(null);
74
- setWorkDir(null);
75
- setSkillRegistry(null);
76
- }
77
48
  async function loadWorkflowFile(path) {
78
49
  const mod = await import(resolve(path));
79
50
  if (typeof mod.default?.run === "function")
@@ -1 +1 @@
1
- {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/cli/run.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/cli/run.ts"],"names":[],"mappings":"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"}
package/dist/context.js CHANGED
@@ -1,4 +1,5 @@
1
- // Module-level singletons shared across the agent session
1
+ import { sessionStore } from "./session.js";
2
+ // Module-level singletons shared across the agent session (legacy fallback)
2
3
  let formatter = null;
3
4
  let workDir = null;
4
5
  let skillRegistry = null;
@@ -6,18 +7,18 @@ export function setFormatter(value) {
6
7
  formatter = value;
7
8
  }
8
9
  export function getFormatter() {
9
- return formatter;
10
+ return sessionStore.getStore()?.formatter ?? formatter;
10
11
  }
11
12
  export function setWorkDir(value) {
12
13
  workDir = value;
13
14
  }
14
15
  export function getWorkDir() {
15
- return workDir;
16
+ return sessionStore.getStore()?.workDir ?? workDir;
16
17
  }
17
18
  export function setSkillRegistry(value) {
18
19
  skillRegistry = value;
19
20
  }
20
21
  export function getSkillRegistry() {
21
- return skillRegistry;
22
+ return sessionStore.getStore()?.skillRegistry ?? skillRegistry;
22
23
  }
23
24
  //# sourceMappingURL=context.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAGA,0DAA0D;AAC1D,IAAI,SAAS,GAA2B,IAAI,CAAC;AAC7C,IAAI,OAAO,GAAkB,IAAI,CAAC;AAClC,IAAI,aAAa,GAAyB,IAAI,CAAC;AAE/C,MAAM,UAAU,YAAY,CAAC,KAA6B;IACxD,SAAS,GAAG,KAAK,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAoB;IAC7C,OAAO,GAAG,KAAK,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAA2B;IAC1D,aAAa,GAAG,KAAK,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO,aAAa,CAAC;AACvB,CAAC"}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,4EAA4E;AAC5E,IAAI,SAAS,GAA2B,IAAI,CAAC;AAC7C,IAAI,OAAO,GAAkB,IAAI,CAAC;AAClC,IAAI,aAAa,GAAyB,IAAI,CAAC;AAE/C,MAAM,UAAU,YAAY,CAAC,KAA6B;IACxD,SAAS,GAAG,KAAK,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO,YAAY,CAAC,QAAQ,EAAE,EAAE,SAAS,IAAI,SAAS,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAoB;IAC7C,OAAO,GAAG,KAAK,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO,YAAY,CAAC,QAAQ,EAAE,EAAE,OAAO,IAAI,OAAO,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAA2B;IAC1D,aAAa,GAAG,KAAK,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO,YAAY,CAAC,QAAQ,EAAE,EAAE,aAAa,IAAI,aAAa,CAAC;AACjE,CAAC"}
package/dist/index.d.ts CHANGED
@@ -5,5 +5,7 @@ export { FeatureSchema, TechStackSchema, ProductSpecSchema, BuildResultSchema, Q
5
5
  export { Pipeline, pipe, Loop, Parallel, Contract, Sprint, type PipelineOptions, type LoopOptions, type ParallelOptions, type ParallelResult, type ContractOptions, type SprintOptions, } from "./orchestration/index.js";
6
6
  export { OutputFormatter } from "./cli/output.js";
7
7
  export { SkillRegistry, type SkillInfo } from "./tools/skills.js";
8
- export { setFormatter, setSkillRegistry, getSkillRegistry } from "./context.js";
8
+ export { Session, type SessionOptions } from "./session.js";
9
+ export { setFormatter, setWorkDir, setSkillRegistry, getSkillRegistry } from "./context.js";
10
+ export { PLAYWRIGHT_MCP_SERVER } from "./utils.js";
9
11
  export { RunContextSchema, type RunContext, type Runnable, type MetricsSnapshot } from "./types.js";
package/dist/index.js CHANGED
@@ -5,6 +5,8 @@ export { FeatureSchema, TechStackSchema, ProductSpecSchema, BuildResultSchema, Q
5
5
  export { Pipeline, pipe, Loop, Parallel, Contract, Sprint, } from "./orchestration/index.js";
6
6
  export { OutputFormatter } from "./cli/output.js";
7
7
  export { SkillRegistry } from "./tools/skills.js";
8
- export { setFormatter, setSkillRegistry, getSkillRegistry } from "./context.js";
8
+ export { Session } from "./session.js";
9
+ export { setFormatter, setWorkDir, setSkillRegistry, getSkillRegistry } from "./context.js";
10
+ export { PLAYWRIGHT_MCP_SERVER } from "./utils.js";
9
11
  export { RunContextSchema } from "./types.js";
10
12
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,IAAI,SAAS,EAAE,KAAK,EAAE,SAAS,EAAsB,MAAM,YAAY,CAAC;AAC7F,OAAO,EACL,QAAQ,EACR,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,GAGf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,aAAa,EAAE,iBAAiB,EAA2B,MAAM,YAAY,CAAC;AAC7H,OAAO,EACL,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EAMd,WAAW,GACZ,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,QAAQ,EACR,IAAI,EACJ,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,MAAM,GAOP,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAkB,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChF,OAAO,EAAE,gBAAgB,EAAwD,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,IAAI,SAAS,EAAE,KAAK,EAAE,SAAS,EAAsB,MAAM,YAAY,CAAC;AAC7F,OAAO,EACL,QAAQ,EACR,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,GAGf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,aAAa,EAAE,iBAAiB,EAA2B,MAAM,YAAY,CAAC;AAC7H,OAAO,EACL,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EAMd,WAAW,GACZ,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,QAAQ,EACR,IAAI,EACJ,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,MAAM,GAOP,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAkB,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAAE,OAAO,EAAuB,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC5F,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAwD,MAAM,YAAY,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ import { OutputFormatter } from "./cli/output.js";
3
+ import { SkillRegistry } from "./tools/skills.js";
4
+ export interface SessionOptions {
5
+ outputDir?: string;
6
+ verbose?: boolean;
7
+ skills?: string[];
8
+ }
9
+ export declare class Session {
10
+ workDir: string;
11
+ formatter: OutputFormatter;
12
+ skillRegistry: SkillRegistry;
13
+ private startTime;
14
+ private endTime;
15
+ constructor(options?: SessionOptions);
16
+ run<T>(fn: () => Promise<T>): Promise<T>;
17
+ get duration(): number;
18
+ private createDefaultSkillRegistry;
19
+ private teardown;
20
+ }
21
+ export declare const sessionStore: AsyncLocalStorage<Session>;
@@ -0,0 +1,57 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ import { mkdirSync } from "node:fs";
3
+ import { join, resolve } from "node:path";
4
+ import { OutputFormatter } from "./cli/output.js";
5
+ import { SkillRegistry } from "./tools/skills.js";
6
+ import { circeHome } from "./utils.js";
7
+ export class Session {
8
+ workDir;
9
+ formatter;
10
+ skillRegistry;
11
+ startTime = null;
12
+ endTime = null;
13
+ constructor(options = {}) {
14
+ this.workDir = resolve(options.outputDir ?? process.cwd());
15
+ mkdirSync(this.workDir, { recursive: true });
16
+ this.formatter = new OutputFormatter(options.verbose);
17
+ this.formatter.setLogFile(join(this.workDir, "circe.log"));
18
+ this.skillRegistry = options.skills
19
+ ? new SkillRegistry(options.skills)
20
+ : this.createDefaultSkillRegistry();
21
+ }
22
+ async run(fn) {
23
+ this.startTime = Date.now();
24
+ return sessionStore.run(this, async () => {
25
+ try {
26
+ return await fn();
27
+ }
28
+ finally {
29
+ this.endTime = Date.now();
30
+ this.teardown();
31
+ }
32
+ });
33
+ }
34
+ get duration() {
35
+ if (this.startTime == null)
36
+ return 0;
37
+ const end = this.endTime ?? Date.now();
38
+ return (end - this.startTime) / 1000;
39
+ }
40
+ createDefaultSkillRegistry() {
41
+ const dirs = [
42
+ join(this.workDir, ".circe", "skills"),
43
+ join(circeHome(), "skills"),
44
+ ];
45
+ return new SkillRegistry(dirs);
46
+ }
47
+ teardown() {
48
+ try {
49
+ this.formatter.close();
50
+ }
51
+ catch (err) {
52
+ console.error("[session] teardown error:", err);
53
+ }
54
+ }
55
+ }
56
+ export const sessionStore = new AsyncLocalStorage();
57
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAQvC,MAAM,OAAO,OAAO;IAClB,OAAO,CAAS;IAChB,SAAS,CAAkB;IAC3B,aAAa,CAAgB;IACrB,SAAS,GAAkB,IAAI,CAAC;IAChC,OAAO,GAAkB,IAAI,CAAC;IAEtC,YAAY,UAA0B,EAAE;QACtC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAC3D,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE7C,IAAI,CAAC,SAAS,GAAG,IAAI,eAAe,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACtD,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC;QAE3D,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,MAAM;YACjC,CAAC,CAAC,IAAI,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC;YACnC,CAAC,CAAC,IAAI,CAAC,0BAA0B,EAAE,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,GAAG,CAAI,EAAoB;QAC/B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE5B,OAAO,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE;YACvC,IAAI,CAAC;gBACH,OAAO,MAAM,EAAE,EAAE,CAAC;YACpB,CAAC;oBAAS,CAAC;gBACT,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBAC1B,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,QAAQ;QACV,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI;YAAE,OAAO,CAAC,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;QACvC,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;IACvC,CAAC;IAEO,0BAA0B;QAChC,MAAM,IAAI,GAAG;YACX,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC;YACtC,IAAI,CAAC,SAAS,EAAE,EAAE,QAAQ,CAAC;SAC5B,CAAC;QACF,OAAO,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAEO,QAAQ;QACd,IAAI,CAAC;YACH,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;QACzB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,GAAG,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;CACF;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,iBAAiB,EAAW,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hham21/circe",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "GAN-style multi-agent framework for application generation using Claude Agent SDK",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",