@lazyingart/agintiflow 0.20.89 → 0.20.91
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lazyingart/agintiflow",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.91",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Low-cost, project-aware Web and CLI agents with DeepSeek/Venice/OpenAI routing, visible tool calls, durable sessions, scouts, AAPS, SCS, and guarded local execution.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -288,6 +288,18 @@ try {
|
|
|
288
288
|
);
|
|
289
289
|
assert(readonlyTestEchoPolicy.allowed, "read-only test/echo probe sequence should not require package-install-policy=allow");
|
|
290
290
|
assert(readonlyTestEchoPolicy.category === "read-only", "read-only test/echo probe sequence should be classified as read-only");
|
|
291
|
+
const pdflatexCompilePolicy = evaluateCommandPolicy(
|
|
292
|
+
'cd profile-latex-20260506 && pdflatex -interaction=nonstopmode -halt-on-error main.tex 2>&1; echo "PDFLATEX_EXIT:$?"',
|
|
293
|
+
dockerWorkspaceNoInstallsPolicy
|
|
294
|
+
);
|
|
295
|
+
assert(pdflatexCompilePolicy.allowed, "workspace-local pdflatex compile should be allowed without package installs");
|
|
296
|
+
assert(pdflatexCompilePolicy.category === "toolchain", "workspace-local pdflatex compile should be classified as toolchain");
|
|
297
|
+
const latexmkCompilePolicy = evaluateCommandPolicy(
|
|
298
|
+
'cd profile-latex-20260506 && latexmk -pdf main.tex 2>&1; echo "LATEXMK_EXIT:$?"',
|
|
299
|
+
dockerWorkspaceNoInstallsPolicy
|
|
300
|
+
);
|
|
301
|
+
assert(latexmkCompilePolicy.allowed, "workspace-local latexmk compile should be allowed without package installs");
|
|
302
|
+
assert(latexmkCompilePolicy.category === "toolchain", "workspace-local latexmk compile should be classified as toolchain");
|
|
291
303
|
const curlPolicy = evaluateCommandPolicy("curl -s -o /dev/null -w '%{http_code}' https://github.com/lazyingart/AgInTiFlow.git", dockerWorkspacePolicy);
|
|
292
304
|
assert(curlPolicy.allowed, "curl URL probe with flags should be allowed in docker-workspace allow mode");
|
|
293
305
|
assert(curlPolicy.needsNetwork, "curl URL probe with flags was not classified as network");
|
|
@@ -318,6 +330,18 @@ try {
|
|
|
318
330
|
assert(cdWorkspacePolicy.allowed, "cd /workspace should be allowed in docker-workspace mode");
|
|
319
331
|
const gitCleanDryRunPolicy = evaluateCommandPolicy("git clean -nd reports", dockerWorkspacePolicy);
|
|
320
332
|
assert(gitCleanDryRunPolicy.allowed, "git clean dry-run should be allowed as read-only inspection evidence");
|
|
333
|
+
const localGitInitPolicy = evaluateCommandPolicy("git init", dockerWorkspaceNoInstallsPolicy);
|
|
334
|
+
assert(localGitInitPolicy.allowed, "local git init should be allowed without package installs");
|
|
335
|
+
assert(localGitInitPolicy.category === "git-workflow", "local git init should be classified as git-workflow");
|
|
336
|
+
const localGitCommitPolicy = evaluateCommandPolicy('git commit -m "Initial local workflow commit"', dockerWorkspaceNoInstallsPolicy);
|
|
337
|
+
assert(localGitCommitPolicy.allowed, "local git commit should be allowed without package installs");
|
|
338
|
+
assert(localGitCommitPolicy.category === "git-workflow", "local git commit should be classified as git-workflow");
|
|
339
|
+
const localGitSwitchPolicy = evaluateCommandPolicy("git switch -c feature-a", dockerWorkspaceNoInstallsPolicy);
|
|
340
|
+
assert(localGitSwitchPolicy.allowed, "local git switch -c should be allowed without package installs");
|
|
341
|
+
const localGitMergePolicy = evaluateCommandPolicy("git merge --ff-only feature-a", dockerWorkspaceNoInstallsPolicy);
|
|
342
|
+
assert(localGitMergePolicy.allowed, "local git fast-forward merge should be allowed without package installs");
|
|
343
|
+
const unsafeRebasePolicy = evaluateCommandPolicy("git rebase main", dockerWorkspaceNoInstallsPolicy);
|
|
344
|
+
assert(!unsafeRebasePolicy.allowed, "git rebase should still require stronger permission because it rewrites history");
|
|
321
345
|
const unsafeCloneTarget = evaluateCommandPolicy("git clone https://github.com/lazyingart/AgInTiFlow.git ../AgInTiFlow", dockerWorkspacePolicy);
|
|
322
346
|
assert(!unsafeCloneTarget.allowed, "git clone outside the workspace should be blocked");
|
|
323
347
|
const blockedClonePolicy = evaluateCommandPolicy("git clone https://github.com/lazyingart/AgInTiFlow.git", {
|
|
@@ -750,6 +774,10 @@ try {
|
|
|
750
774
|
"command_policy_readonly_probe_sequence_no_installs",
|
|
751
775
|
"command_policy_readonly_version_pipeline_no_installs",
|
|
752
776
|
"command_policy_readonly_test_echo_no_installs",
|
|
777
|
+
"command_policy_pdflatex_compile_no_installs",
|
|
778
|
+
"command_policy_latexmk_compile_no_installs",
|
|
779
|
+
"command_policy_local_git_workflow_no_installs",
|
|
780
|
+
"command_policy_git_rebase_still_guarded",
|
|
753
781
|
"command_policy_git_clone_network",
|
|
754
782
|
"command_policy_safe_chmod_sequence",
|
|
755
783
|
"command_policy_cd_workspace",
|
|
@@ -20,4 +20,6 @@ tools:
|
|
|
20
20
|
|
|
21
21
|
Always inspect `git status --short` and relevant diffs before committing or pushing. Keep commits scoped and stop on conflicts, divergence, or unrelated dirty work.
|
|
22
22
|
|
|
23
|
+
For local workflow practice or repository setup, prefer a disposable subdirectory if the user did not clearly target the current repository. Configure only local git identity (`git config user.name`, `git config user.email`) inside that repo; never change global git config. Use accurate git scenarios: a fast-forward merge means the target branch has not diverged; a non-fast-forward merge intentionally creates a merge commit after both branches diverge; a rebase rewrites local branch commits and should be used only in an explicitly disposable/local branch or after user approval.
|
|
24
|
+
|
|
23
25
|
Use `gh` for PR/release/status workflows when authenticated. Fold long command output but preserve key errors, URLs, branch names, and commit hashes.
|
package/src/command-policy.js
CHANGED
|
@@ -71,8 +71,19 @@ const NETWORK_FETCH_PATTERNS = [
|
|
|
71
71
|
];
|
|
72
72
|
|
|
73
73
|
const GIT_WORKFLOW_PATTERNS = [
|
|
74
|
+
/^git\s+init(?:\s+(?:\.|[-\w./]+))?$/,
|
|
75
|
+
/^git\s+config(?:\s+--local)?\s+user\.(?:name|email)\s+(['"])[^'"\n]{1,160}\1$/,
|
|
76
|
+
/^git\s+config(?:\s+--local)?\s+init\.defaultBranch\s+(?:main|master|trunk|develop)$/,
|
|
74
77
|
/^git\s+add(?:\s+[-\w./*]+)+$/,
|
|
75
|
-
/^git\s+
|
|
78
|
+
/^git\s+add\s+-A$/,
|
|
79
|
+
/^git\s+commit\s+(?:(?:-a|--allow-empty)\s+)*-m\s+(['"])[^'"\n]{1,220}\1$/,
|
|
80
|
+
/^git\s+branch\s+-M\s+[A-Za-z0-9][-\w./]*$/,
|
|
81
|
+
/^git\s+branch\s+[A-Za-z0-9][-\w./]*$/,
|
|
82
|
+
/^git\s+switch\s+(?:-c\s+)?[A-Za-z0-9][-\w./]*$/,
|
|
83
|
+
/^git\s+checkout\s+-b\s+[A-Za-z0-9][-\w./]*$/,
|
|
84
|
+
/^git\s+merge\s+--ff-only\s+[A-Za-z0-9][-\w./]*$/,
|
|
85
|
+
/^git\s+merge\s+--no-ff\s+--no-edit\s+[A-Za-z0-9][-\w./]*$/,
|
|
86
|
+
/^git\s+merge\s+[A-Za-z0-9][-\w./]*\s+--no-ff\s+--no-edit$/,
|
|
76
87
|
/^git\s+fetch(?:\s+[-\w./:=]+)*$/,
|
|
77
88
|
/^git\s+pull\s+--ff-only(?:\s+[-\w./:=]+)*$/,
|
|
78
89
|
/^git\s+push(?:\s+[-\w./:=]+)*$/,
|
|
@@ -264,8 +275,23 @@ function classifyGitClone(normalized) {
|
|
|
264
275
|
};
|
|
265
276
|
}
|
|
266
277
|
|
|
278
|
+
function classifyGitWorkflow(normalized) {
|
|
279
|
+
if (!matchAny(GIT_WORKFLOW_PATTERNS, normalized)) return null;
|
|
280
|
+
const remote = /^git\s+(fetch|pull|push)\b/.test(normalized);
|
|
281
|
+
const writesWorkspace = !/^git\s+fetch\b/.test(normalized);
|
|
282
|
+
return {
|
|
283
|
+
category: remote ? "git-remote" : "git-workflow",
|
|
284
|
+
needsNetwork: remote,
|
|
285
|
+
writesWorkspace,
|
|
286
|
+
reason:
|
|
287
|
+
remote
|
|
288
|
+
? "Git remote workflow command. Agent should inspect status/diff first and stop on divergence or conflicts."
|
|
289
|
+
: "Local git workflow command. Agent should inspect status/diff first and stop on conflicts or unrelated dirty work.",
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
|
|
267
293
|
function classifySimpleCommand(normalized) {
|
|
268
|
-
const
|
|
294
|
+
const benignRedirectCommand = stripBenignRedirections(normalized);
|
|
269
295
|
if (ALWAYS_BLOCKED_PATTERNS.some((pattern) => pattern.test(normalized))) {
|
|
270
296
|
return { category: "blocked", reason: "Command is blocked because it may expose secrets or publish packages." };
|
|
271
297
|
}
|
|
@@ -274,6 +300,8 @@ function classifySimpleCommand(normalized) {
|
|
|
274
300
|
}
|
|
275
301
|
const gitCleanDryRun = classifyGitCleanDryRun(normalized);
|
|
276
302
|
if (gitCleanDryRun) return gitCleanDryRun;
|
|
303
|
+
const gitWorkflowClassification = classifyGitWorkflow(normalized);
|
|
304
|
+
if (gitWorkflowClassification) return gitWorkflowClassification;
|
|
277
305
|
if (matchAny(UNSAFE_GIT_PATTERNS, normalized)) {
|
|
278
306
|
return {
|
|
279
307
|
category: "destructive",
|
|
@@ -305,20 +333,10 @@ function classifySimpleCommand(normalized) {
|
|
|
305
333
|
reason: `Command changes workspace file mode: ${normalized}`,
|
|
306
334
|
};
|
|
307
335
|
}
|
|
308
|
-
if (matchAny(GIT_WORKFLOW_PATTERNS, normalized)) {
|
|
309
|
-
const remote = /^git\s+(fetch|pull|push)\b/.test(normalized);
|
|
310
|
-
const writesWorkspace = /^git\s+(add|commit|pull)\b/.test(normalized);
|
|
311
|
-
return {
|
|
312
|
-
category: remote ? "git-remote" : "git-workflow",
|
|
313
|
-
needsNetwork: remote,
|
|
314
|
-
writesWorkspace,
|
|
315
|
-
reason: "Git workflow command. Agent should run git status/diff first and stop on conflicts or divergence.",
|
|
316
|
-
};
|
|
317
|
-
}
|
|
318
336
|
const gitCloneClassification = classifyGitClone(normalized);
|
|
319
337
|
if (gitCloneClassification) return gitCloneClassification;
|
|
320
338
|
|
|
321
|
-
const unquoted = stripQuotedSegments(
|
|
339
|
+
const unquoted = stripQuotedSegments(benignRedirectCommand);
|
|
322
340
|
const lowered = ` ${unquoted.toLowerCase()} `;
|
|
323
341
|
if (BLOCKED_WRITE_TOKENS.some((part) => lowered.includes(part))) {
|
|
324
342
|
return {
|
|
@@ -337,25 +355,25 @@ function classifySimpleCommand(normalized) {
|
|
|
337
355
|
};
|
|
338
356
|
}
|
|
339
357
|
|
|
340
|
-
if (matchAny(READ_ONLY_PATTERNS,
|
|
358
|
+
if (matchAny(READ_ONLY_PATTERNS, benignRedirectCommand) || isReadOnlyFindCommand(normalized)) {
|
|
341
359
|
return { category: "read-only", needsNetwork: false, writesWorkspace: false };
|
|
342
360
|
}
|
|
343
|
-
if (matchAny(TEST_PATTERNS,
|
|
361
|
+
if (matchAny(TEST_PATTERNS, benignRedirectCommand)) {
|
|
344
362
|
return { category: "test", needsNetwork: false, writesWorkspace: false };
|
|
345
363
|
}
|
|
346
|
-
if (matchAny(TOOLCHAIN_PATTERNS,
|
|
364
|
+
if (matchAny(TOOLCHAIN_PATTERNS, benignRedirectCommand)) {
|
|
347
365
|
return { category: "toolchain", needsNetwork: false, writesWorkspace: true };
|
|
348
366
|
}
|
|
349
|
-
if (matchAny(NETWORK_FETCH_PATTERNS,
|
|
350
|
-
return { category: "network-fetch", needsNetwork: true, writesWorkspace: /(\s-o\s|\s-O\s)/.test(
|
|
367
|
+
if (matchAny(NETWORK_FETCH_PATTERNS, benignRedirectCommand)) {
|
|
368
|
+
return { category: "network-fetch", needsNetwork: true, writesWorkspace: /(\s-o\s|\s-O\s)/.test(benignRedirectCommand) };
|
|
351
369
|
}
|
|
352
|
-
if (matchAny(SYSTEM_PACKAGE_INSTALL_PATTERNS,
|
|
370
|
+
if (matchAny(SYSTEM_PACKAGE_INSTALL_PATTERNS, benignRedirectCommand)) {
|
|
353
371
|
return { category: "system-package-install", needsNetwork: true, writesWorkspace: false, requiresDockerRoot: true };
|
|
354
372
|
}
|
|
355
|
-
if (matchAny(PACKAGE_INSTALL_PATTERNS,
|
|
373
|
+
if (matchAny(PACKAGE_INSTALL_PATTERNS, benignRedirectCommand)) {
|
|
356
374
|
return { category: "package-install", needsNetwork: true, writesWorkspace: true };
|
|
357
375
|
}
|
|
358
|
-
if (matchAny(ENV_SETUP_PATTERNS,
|
|
376
|
+
if (matchAny(ENV_SETUP_PATTERNS, benignRedirectCommand)) {
|
|
359
377
|
return { category: "env-setup", needsNetwork: false, writesWorkspace: true };
|
|
360
378
|
}
|
|
361
379
|
|
package/src/task-profiles.js
CHANGED
|
@@ -255,7 +255,7 @@ export const TASK_PROFILES = {
|
|
|
255
255
|
id: "github",
|
|
256
256
|
label: "GitHub maintenance",
|
|
257
257
|
prompt:
|
|
258
|
-
"Bias toward safe git and GitHub maintenance while still fixing code/docs when asked. Always inspect git status and remotes first, separate unrelated changes, run relevant checks before commits, use gh when available for PR/issues/releases, prefer fast-forward pulls, and stop on conflicts or ambiguous history.",
|
|
258
|
+
"Bias toward safe git and GitHub maintenance while still fixing code/docs when asked. Always inspect git status and remotes first, separate unrelated changes, run relevant checks before commits, use gh when available for PR/issues/releases, prefer fast-forward pulls, and stop on conflicts or ambiguous history. For local workflow practice, use a disposable subdirectory, set only local git identity, avoid real remotes unless explicitly requested, and describe fast-forward, non-fast-forward merge, and rebase evidence accurately.",
|
|
259
259
|
tools: ["shell", "files", "web_search", "inspect_project"],
|
|
260
260
|
},
|
|
261
261
|
word: {
|