create-loopengine 0.1.14 → 0.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -61,8 +61,8 @@ own `discoverAgents`: it scans `agents/` and keys each entry by
61
61
  one new file, not a rewrite and not a registry edit either. See
62
62
  [loopengine's own README](https://github.com/evanyan22/loopengine) for the
63
63
  full `AgentConfig` surface: permission rules, skills, context-budget
64
- recovery, and how to wire a real model (Anthropic, OpenAI, or DeepSeek —
65
- all three included).
64
+ recovery, and how to wire a real model (Anthropic, OpenAI, DeepSeek,
65
+ Kimi, GLM, or Gemini — all six included).
66
66
 
67
67
  ## Add another agent
68
68
 
@@ -120,6 +120,49 @@ Each of the five template-owned files gets one of:
120
120
  loopengine@latest` (and `actauth`/`skillgarden` if you use them directly)
121
121
  separately to pick those up.
122
122
 
123
+ ## Running in production
124
+
125
+ `npm run dev` (`tsx watch`) restarts on every file change — fine for
126
+ local iteration, wrong for a real server, since a restart drops every
127
+ in-flight request and any pending live approval/question (see
128
+ loopengine's own README on durable vs. live approvers if that matters to
129
+ you). Use [pm2](https://pm2.keymetrics.io/) to run the plain, non-watch
130
+ server instead, with restart-on-crash:
131
+
132
+ ```bash
133
+ pm2 start npx --name my-agents --interpreter none -- loopengine serve
134
+ pm2 save # persist across reboots
135
+ pm2 startup # (one-time) launch pm2 itself on boot
136
+ ```
137
+
138
+ `--interpreter none` matters — without it pm2 may try to run `npx`
139
+ through `node` directly, which fails since it's a shell-invokable binary,
140
+ not a bare `.js` file. `--` separates pm2's own flags from the command's
141
+ own args (`loopengine serve`).
142
+
143
+ Two gotchas worth knowing before they cost you a debugging session:
144
+
145
+ - **`npm` is not `npx`.** `pm2 start npm --name my-agents -- loopengine
146
+ serve` does *not* work — `npm <args>` treats its args as npm's own
147
+ subcommands, not a binary to run, so it fails with `Unknown command:
148
+ "loopengine"`. If you'd rather invoke via `npm`, add a `"start":
149
+ "loopengine serve"` script to `package.json` first, then `pm2 start npm
150
+ --name my-agents -- start` (npm special-cases `start` as a shorthand
151
+ for running that script, unlike arbitrary script names).
152
+ - **pm2 remembers a name's original `cwd`/script, not whatever you pass
153
+ next time.** Running `pm2 start ... --name my-agents` again after
154
+ moving/recreating the project directory just restarts the *already-
155
+ registered* process with its *original* path — your new files are
156
+ never even read. Run `pm2 delete my-agents` first if the project's
157
+ location changed, then start fresh.
158
+
159
+ `pm2 logs my-agents` tails output; `pm2 restart my-agents` after any
160
+ manual edit to `adapters/http.ts`/`adapters/cli.ts`/`agent-registry.ts`
161
+ (see "Upgrading" above) or an env var change — those don't take effect
162
+ until the process restarts. Adding a skill or tool through the Admin UI
163
+ does *not* need a restart — that's applied to the already-running process
164
+ directly.
165
+
123
166
  ## Status
124
167
 
125
168
  Verified end to end against the real published packages: `npm create
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-loopengine",
3
- "version": "0.1.14",
3
+ "version": "0.1.15",
4
4
  "description": "Scaffold a new loopengine agent project — a runnable HTTP server with one example agent, in your own repo.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -645,7 +645,14 @@ function parseAgentTemplateOptions(body: Record<string, unknown>): { ok: true; v
645
645
  return { ok: false, error: 'model must be an object' }
646
646
  }
647
647
  const provider = (body.model as Record<string, unknown>).provider
648
- if (provider !== 'anthropic' && provider !== 'openai' && provider !== 'deepseek') {
648
+ if (
649
+ provider !== 'anthropic' &&
650
+ provider !== 'openai' &&
651
+ provider !== 'deepseek' &&
652
+ provider !== 'kimi' &&
653
+ provider !== 'glm' &&
654
+ provider !== 'gemini'
655
+ ) {
649
656
  return { ok: false, error: `unsupported model provider '${String(provider)}'` }
650
657
  }
651
658
  const modelName = (body.model as Record<string, unknown>).model
@@ -9,7 +9,7 @@
9
9
  "cli": "tsx adapters/cli.ts"
10
10
  },
11
11
  "dependencies": {
12
- "loopengine": "^0.1.6",
12
+ "loopengine": "^0.1.7",
13
13
  "actauth": "^0.0.12",
14
14
  "skillgarden": "^0.0.9"
15
15
  },